Flutter Engine
The Flutter Engine
kernel_fingerprints.cc
Go to the documentation of this file.
1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
7
8#define H (translation_helper_)
9#define I Isolate::Current()
10
11namespace dart {
12namespace kernel {
13
15 public:
17 TranslationHelper* translation_helper,
18 const TypedDataView& data,
19 intptr_t data_program_offset)
20 : KernelReaderHelper(zone, translation_helper, data, data_program_offset),
21 hash_(0) {}
22
26
27 static uint32_t CalculateHash(uint32_t current, uint32_t val) {
28 return current * 31 + val;
29 }
30
31 private:
32 void BuildHash(uint32_t val);
33 void CalculateConstructorFingerprint();
34 void CalculateArgumentsFingerprint();
35 void CalculateVariableDeclarationFingerprint();
36 void CalculateStatementListFingerprint();
37 void CalculateListOfExpressionsFingerprint();
38 void CalculateListOfNamedExpressionsFingerprint();
39 void CalculateListOfDartTypesFingerprint();
40 void CalculateListOfVariableDeclarationsFingerprint();
41 void CalculateStringReferenceFingerprint();
42 void CalculateListOfStringsFingerprint();
43 void CalculateTypeParameterFingerprint();
44 void CalculateTypeParametersListFingerprint();
45 void CalculateCanonicalNameFingerprint();
46 void CalculateInterfaceMemberNameFingerprint();
47 void CalculateInitializerFingerprint();
48 void CalculateDartTypeFingerprint();
49 void CalculateOptionalDartTypeFingerprint();
50 void CalculateInterfaceTypeFingerprint(bool simple);
51 void CalculateFunctionTypeFingerprint(bool simple);
52 void CalculateGetterNameFingerprint();
53 void CalculateSetterNameFingerprint();
54 void CalculateMethodNameFingerprint();
55 void CalculateExpressionFingerprint();
56 void CalculateStatementFingerprint();
57 void CalculateFunctionNodeFingerprint();
58
59 uint32_t hash_;
60
61 DISALLOW_COPY_AND_ASSIGN(KernelFingerprintHelper);
62};
63
64void KernelFingerprintHelper::BuildHash(uint32_t val) {
65 hash_ = CalculateHash(hash_, val);
66}
67
68void KernelFingerprintHelper::CalculateConstructorFingerprint() {
69 ConstructorHelper helper(this);
70
71 helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
72 CalculateListOfExpressionsFingerprint();
73 CalculateFunctionNodeFingerprint();
74 intptr_t len = ReadListLength();
75 for (intptr_t i = 0; i < len; ++i) {
76 CalculateInitializerFingerprint();
77 }
78 helper.SetJustRead(ConstructorHelper::kInitializers);
79 BuildHash(helper.flags_);
80}
81
82void KernelFingerprintHelper::CalculateArgumentsFingerprint() {
83 BuildHash(ReadUInt()); // read argument count.
84
85 CalculateListOfDartTypesFingerprint(); // read list of types.
86 CalculateListOfExpressionsFingerprint(); // read positional.
87 CalculateListOfNamedExpressionsFingerprint(); // read named.
88}
89
90void KernelFingerprintHelper::CalculateVariableDeclarationFingerprint() {
91 VariableDeclarationHelper helper(this);
92
93 helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations);
94 CalculateListOfExpressionsFingerprint();
96
97 helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
98 // We don't need to use the helper after this point.
99 CalculateDartTypeFingerprint();
100 if (ReadTag() == kSomething) {
101 CalculateExpressionFingerprint();
102 }
103
104 BuildHash(helper.flags_);
105}
106
107void KernelFingerprintHelper::CalculateStatementListFingerprint() {
108 intptr_t list_length = ReadListLength(); // read list length.
109 for (intptr_t i = 0; i < list_length; ++i) {
110 CalculateStatementFingerprint(); // read ith expression.
111 }
112}
113
114void KernelFingerprintHelper::CalculateListOfExpressionsFingerprint() {
115 intptr_t list_length = ReadListLength(); // read list length.
116 for (intptr_t i = 0; i < list_length; ++i) {
117 CalculateExpressionFingerprint(); // read ith expression.
118 }
119}
120
121void KernelFingerprintHelper::CalculateListOfNamedExpressionsFingerprint() {
122 const intptr_t list_length = ReadListLength(); // read list length.
123 for (intptr_t i = 0; i < list_length; ++i) {
124 CalculateStringReferenceFingerprint(); // read ith name index.
125 CalculateExpressionFingerprint(); // read ith expression.
126 }
127}
128
129void KernelFingerprintHelper::CalculateListOfDartTypesFingerprint() {
130 intptr_t list_length = ReadListLength(); // read list length.
131 for (intptr_t i = 0; i < list_length; ++i) {
132 CalculateDartTypeFingerprint(); // read ith type.
133 }
134}
135
136void KernelFingerprintHelper::CalculateStringReferenceFingerprint() {
137 BuildHash(
138 H.DartString(ReadStringReference()).Hash()); // read ith string index.
139}
140
141void KernelFingerprintHelper::CalculateListOfStringsFingerprint() {
142 intptr_t list_length = ReadListLength(); // read list length.
143 for (intptr_t i = 0; i < list_length; ++i) {
144 CalculateStringReferenceFingerprint(); // read ith string index.
145 }
146}
147
148void KernelFingerprintHelper::CalculateListOfVariableDeclarationsFingerprint() {
149 intptr_t list_length = ReadListLength(); // read list length.
150 for (intptr_t i = 0; i < list_length; ++i) {
151 // read ith variable declaration.
152 CalculateVariableDeclarationFingerprint();
153 }
154}
155
156void KernelFingerprintHelper::CalculateTypeParameterFingerprint() {
157 TypeParameterHelper helper(this);
158
159 helper.ReadUntilExcluding(TypeParameterHelper::kAnnotations);
160 CalculateListOfExpressionsFingerprint();
161 helper.SetJustRead(TypeParameterHelper::kAnnotations);
162
163 helper.ReadUntilExcluding(TypeParameterHelper::kVariance);
164 Variance variance = ReadVariance();
165 BuildHash(variance);
166 helper.SetJustRead(TypeParameterHelper::kVariance);
167
168 helper.ReadUntilExcluding(TypeParameterHelper::kBound);
169 // The helper isn't needed after this point.
170 CalculateDartTypeFingerprint(); // read bound
171 CalculateDartTypeFingerprint(); // read default type
172 BuildHash(helper.flags_);
173}
174
175void KernelFingerprintHelper::CalculateTypeParametersListFingerprint() {
176 intptr_t list_length = ReadListLength(); // read list length.
177 for (intptr_t i = 0; i < list_length; ++i) {
178 CalculateTypeParameterFingerprint();
179 }
180}
181
182void KernelFingerprintHelper::CalculateCanonicalNameFingerprint() {
183 const StringIndex i = H.CanonicalNameString(ReadCanonicalNameReference());
184 BuildHash(H.DartString(i).Hash());
185}
186
187void KernelFingerprintHelper::CalculateInterfaceMemberNameFingerprint() {
188 CalculateCanonicalNameFingerprint();
189 ReadCanonicalNameReference(); // read target_origin_reference
190}
191
192void KernelFingerprintHelper::CalculateInitializerFingerprint() {
193 Tag tag = ReadTag();
194 ReadByte(); // read isSynthetic flag.
195 switch (tag) {
196 case kInvalidInitializer:
197 return;
198 case kFieldInitializer:
199 ReadPosition(); // read position.
200 BuildHash(H.DartFieldName(ReadCanonicalNameReference()).Hash());
201 CalculateExpressionFingerprint(); // read value.
202 return;
203 case kSuperInitializer:
204 ReadPosition(); // read position.
205 CalculateCanonicalNameFingerprint(); // read target_reference
206 CalculateArgumentsFingerprint(); // read arguments.
207 return;
208 case kRedirectingInitializer:
209 ReadPosition(); // read position.
210 CalculateCanonicalNameFingerprint(); // read target_reference
211 CalculateArgumentsFingerprint(); // read arguments.
212 return;
213 case kLocalInitializer:
214 CalculateVariableDeclarationFingerprint(); // read variable.
215 return;
216 case kAssertInitializer:
217 CalculateStatementFingerprint();
218 return;
219 default:
220 ReportUnexpectedTag("initializer", tag);
221 UNREACHABLE();
222 }
223}
224
225void KernelFingerprintHelper::CalculateDartTypeFingerprint() {
226 Tag tag = ReadTag();
227 BuildHash(tag);
228 switch (tag) {
229 case kInvalidType:
230 case kDynamicType:
231 case kVoidType:
232 case kNullType:
233 // those contain nothing.
234 break;
235 case kNeverType:
236 BuildHash(static_cast<uint32_t>(ReadNullability()));
237 break;
238 case kInterfaceType:
239 CalculateInterfaceTypeFingerprint(false);
240 break;
241 case kSimpleInterfaceType:
242 CalculateInterfaceTypeFingerprint(true);
243 break;
244 case kFunctionType:
245 CalculateFunctionTypeFingerprint(false);
246 break;
247 case kSimpleFunctionType:
248 CalculateFunctionTypeFingerprint(true);
249 break;
250 case kTypeParameterType: {
251 Nullability nullability = ReadNullability();
252 BuildHash(static_cast<uint32_t>(nullability));
253 ReadUInt(); // read index for parameter.
254 break;
255 }
256 case kIntersectionType:
257 CalculateDartTypeFingerprint(); // read left;
258 CalculateDartTypeFingerprint(); // read right;
259 break;
260 case kRecordType: {
261 BuildHash(static_cast<uint32_t>(ReadNullability()));
262 CalculateListOfDartTypesFingerprint();
263 const intptr_t named_count = ReadListLength();
264 BuildHash(named_count);
265 for (intptr_t i = 0; i < named_count; ++i) {
266 CalculateStringReferenceFingerprint();
267 CalculateDartTypeFingerprint();
268 ReadFlags();
269 }
270 break;
271 }
272 case kExtensionType: {
273 // We skip the extension type and only use the type erasure.
275 SkipCanonicalNameReference(); // read index for canonical name.
276 SkipListOfDartTypes(); // read type arguments
277 CalculateDartTypeFingerprint(); // read type erasure.
278 break;
279 }
280 case kFutureOrType:
281 BuildHash(static_cast<uint32_t>(ReadNullability()));
282 CalculateDartTypeFingerprint(); // read type argument.
283 break;
284 default:
285 ReportUnexpectedTag("type", tag);
286 UNREACHABLE();
287 }
288}
289
290void KernelFingerprintHelper::CalculateOptionalDartTypeFingerprint() {
291 Tag tag = ReadTag(); // read tag.
292 BuildHash(tag);
293 if (tag == kNothing) {
294 return;
295 }
296 ASSERT(tag == kSomething);
297 CalculateDartTypeFingerprint(); // read type.
298}
299
300void KernelFingerprintHelper::CalculateInterfaceTypeFingerprint(bool simple) {
301 Nullability nullability = ReadNullability();
302 BuildHash(static_cast<uint32_t>(nullability));
303 NameIndex kernel_class = ReadCanonicalNameReference();
304 ASSERT(H.IsClass(kernel_class));
305 const String& class_name = H.DartClassName(kernel_class);
306 NameIndex kernel_library = H.CanonicalNameParent(kernel_class);
307 const String& library_name =
308 H.DartSymbolPlain(H.CanonicalNameString(kernel_library));
309 BuildHash(class_name.Hash());
310 BuildHash(library_name.Hash());
311 if (!simple) {
312 CalculateListOfDartTypesFingerprint(); // read list of types.
313 }
314}
315
316void KernelFingerprintHelper::CalculateFunctionTypeFingerprint(bool simple) {
317 Nullability nullability = ReadNullability();
318 BuildHash(static_cast<uint32_t>(nullability));
319
320 if (!simple) {
321 CalculateTypeParametersListFingerprint(); // read type_parameters.
322 BuildHash(ReadUInt()); // read required parameter count.
323 BuildHash(ReadUInt()); // read total parameter count.
324 }
325
326 CalculateListOfDartTypesFingerprint(); // read positional_parameters types.
327
328 if (!simple) {
329 const intptr_t named_count =
330 ReadListLength(); // read named_parameters list length.
331 BuildHash(named_count);
332 for (intptr_t i = 0; i < named_count; ++i) {
333 // read string reference (i.e. named_parameters[i].name).
334 CalculateStringReferenceFingerprint();
335 CalculateDartTypeFingerprint(); // read named_parameters[i].type.
336 BuildHash(ReadFlags()); // read flags.
337 }
338 }
339
340 CalculateDartTypeFingerprint(); // read return type.
341}
342
343void KernelFingerprintHelper::CalculateGetterNameFingerprint() {
344 const NameIndex name = ReadCanonicalNameReference();
345 if (!H.IsRoot(name) && H.IsGetter(name)) {
346 BuildHash(H.DartGetterName(name).Hash());
347 }
348 ReadCanonicalNameReference(); // read interface_target_origin_reference
349}
350
351void KernelFingerprintHelper::CalculateSetterNameFingerprint() {
352 const NameIndex name = ReadCanonicalNameReference();
353 if (!H.IsRoot(name)) {
354 BuildHash(H.DartSetterName(name).Hash());
355 }
356 ReadCanonicalNameReference(); // read interface_target_origin_reference
357}
358
359void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
360 const NameIndex name =
361 ReadCanonicalNameReference(); // read interface_target_reference.
362 if (!H.IsRoot(name)) {
363 BuildHash(H.DartProcedureName(name).Hash());
364 }
365 ReadCanonicalNameReference(); // read interface_target_origin_reference
366}
367
368void KernelFingerprintHelper::CalculateExpressionFingerprint() {
369 uint8_t payload = 0;
370 Tag tag = ReadTag(&payload);
371 BuildHash(tag);
372 switch (tag) {
373 case kInvalidExpression:
374 ReadPosition();
375 CalculateStringReferenceFingerprint();
376 if (ReadTag() == kSomething) {
377 CalculateExpressionFingerprint(); // read expression.
378 }
379 return;
380 case kVariableGet:
381 ReadPosition(); // read position.
382 ReadUInt(); // read kernel position.
383 ReadUInt(); // read relative variable index.
384 CalculateOptionalDartTypeFingerprint(); // read promoted type.
385 return;
386 case kSpecializedVariableGet:
387 ReadPosition(); // read position.
388 ReadUInt(); // read kernel position.
389 return;
390 case kVariableSet:
391 ReadPosition(); // read position.
392 ReadUInt(); // read kernel position.
393 ReadUInt(); // read relative variable index.
394 CalculateExpressionFingerprint(); // read expression.
395 return;
396 case kSpecializedVariableSet:
397 ReadPosition(); // read position.
398 ReadUInt(); // read kernel position.
399 CalculateExpressionFingerprint(); // read expression.
400 return;
401 case kInstanceGet:
402 ReadByte(); // read kind.
403 ReadPosition(); // read position.
404 CalculateExpressionFingerprint(); // read receiver.
405 BuildHash(ReadNameAsGetterName().Hash()); // read name.
406 SkipDartType(); // read result_type.
407 CalculateGetterNameFingerprint(); // read interface_target_reference.
408 return;
409 case kDynamicGet:
410 ReadByte(); // read kind.
411 ReadPosition(); // read position.
412 CalculateExpressionFingerprint(); // read receiver.
413 BuildHash(ReadNameAsGetterName().Hash()); // read name.
414 return;
415 case kInstanceTearOff:
416 ReadByte(); // read kind.
417 ReadPosition(); // read position.
418 CalculateExpressionFingerprint(); // read receiver.
419 BuildHash(ReadNameAsGetterName().Hash()); // read name.
420 SkipDartType(); // read result_type.
421 CalculateGetterNameFingerprint(); // read interface_target_reference.
422 return;
423 case kFunctionTearOff:
424 // Removed by lowering kernel transformation.
425 UNREACHABLE();
426 break;
427 case kInstanceSet:
428 ReadByte(); // read kind.
429 ReadPosition(); // read position.
430 CalculateExpressionFingerprint(); // read receiver.
431 BuildHash(ReadNameAsSetterName().Hash()); // read name.
432 CalculateExpressionFingerprint(); // read value.
433 CalculateSetterNameFingerprint(); // read interface_target_reference.
434 return;
435 case kDynamicSet:
436 ReadByte(); // read kind.
437 ReadPosition(); // read position.
438 CalculateExpressionFingerprint(); // read receiver.
439 BuildHash(ReadNameAsSetterName().Hash()); // read name.
440 CalculateExpressionFingerprint(); // read value.
441 return;
442 case kAbstractSuperPropertyGet:
443 // Abstract super property getters must be converted into super property
444 // getters during mixin transformation.
445 UNREACHABLE();
446 break;
447 case kAbstractSuperPropertySet:
448 // Abstract super property setters must be converted into super property
449 // setters during mixin transformation.
450 UNREACHABLE();
451 break;
452 case kSuperPropertyGet:
453 ReadPosition(); // read position.
454 BuildHash(ReadNameAsGetterName().Hash()); // read name.
455 CalculateGetterNameFingerprint(); // read interface_target_reference.
456 return;
457 case kSuperPropertySet:
458 ReadPosition(); // read position.
459 BuildHash(ReadNameAsSetterName().Hash()); // read name.
460 CalculateExpressionFingerprint(); // read value.
461 CalculateSetterNameFingerprint(); // read interface_target_reference.
462 return;
463 case kStaticGet:
464 ReadPosition(); // read position.
465 CalculateCanonicalNameFingerprint(); // read target_reference.
466 return;
467 case kStaticSet:
468 ReadPosition(); // read position.
469 CalculateCanonicalNameFingerprint(); // read target_reference.
470 CalculateExpressionFingerprint(); // read expression.
471 return;
472 case kInstanceInvocation:
473 ReadByte(); // read kind.
474 ReadFlags(); // read flags.
475 ReadPosition(); // read position.
476 CalculateExpressionFingerprint(); // read receiver.
477 BuildHash(ReadNameAsMethodName().Hash()); // read name.
478 CalculateArgumentsFingerprint(); // read arguments.
479 SkipDartType(); // read function_type.
480 CalculateMethodNameFingerprint(); // read interface_target_reference.
481 return;
482 case kDynamicInvocation:
483 ReadByte(); // read kind.
484 ReadByte(); // read flags.
485 ReadPosition(); // read position.
486 CalculateExpressionFingerprint(); // read receiver.
487 BuildHash(ReadNameAsMethodName().Hash()); // read name.
488 CalculateArgumentsFingerprint(); // read arguments.
489 return;
490 case kLocalFunctionInvocation:
491 ReadPosition(); // read position.
492 ReadUInt(); // read variable kernel position.
493 ReadUInt(); // read relative variable index.
494 CalculateArgumentsFingerprint(); // read arguments.
495 SkipDartType(); // read function_type.
496 return;
497 case kFunctionInvocation:
498 BuildHash(ReadByte()); // read kind.
499 ReadPosition(); // read position.
500 CalculateExpressionFingerprint(); // read receiver.
501 CalculateArgumentsFingerprint(); // read arguments.
502 SkipDartType(); // read function_type.
503 return;
504 case kEqualsCall:
505 ReadPosition(); // read position.
506 CalculateExpressionFingerprint(); // read left.
507 CalculateExpressionFingerprint(); // read right.
508 SkipDartType(); // read function_type.
509 CalculateMethodNameFingerprint(); // read interface_target_reference.
510 return;
511 case kEqualsNull:
512 ReadPosition(); // read position.
513 CalculateExpressionFingerprint(); // read expression.
514 return;
515 case kAbstractSuperMethodInvocation:
516 // Abstract super method invocations must be converted into super
517 // method invocations during mixin transformation.
518 UNREACHABLE();
519 break;
520 case kSuperMethodInvocation:
521 ReadPosition(); // read position.
522 BuildHash(ReadNameAsMethodName().Hash()); // read name.
523 CalculateArgumentsFingerprint(); // read arguments.
524 CalculateInterfaceMemberNameFingerprint(); // read target_reference.
525 return;
526 case kStaticInvocation:
527 ReadPosition(); // read position.
528 CalculateCanonicalNameFingerprint(); // read target_reference.
529 CalculateArgumentsFingerprint(); // read arguments.
530 return;
531 case kConstructorInvocation:
532 ReadPosition(); // read position.
533 CalculateCanonicalNameFingerprint(); // read target_reference.
534 CalculateArgumentsFingerprint(); // read arguments.
535 return;
536 case kNot:
537 ReadPosition(); // read position.
538 CalculateExpressionFingerprint(); // read expression.
539 return;
540 case kNullCheck:
541 ReadPosition(); // read position.
542 CalculateExpressionFingerprint(); // read expression.
543 return;
544 case kLogicalExpression:
545 ReadPosition(); // read position.
546 CalculateExpressionFingerprint(); // read left.
547 SkipBytes(1); // read operator.
548 CalculateExpressionFingerprint(); // read right.
549 return;
550 case kConditionalExpression:
551 ReadPosition(); // read position.
552 CalculateExpressionFingerprint(); // read condition.
553 CalculateExpressionFingerprint(); // read then.
554 CalculateExpressionFingerprint(); // read otherwise.
555 CalculateOptionalDartTypeFingerprint(); // read unused static type.
556 return;
557 case kStringConcatenation:
558 ReadPosition(); // read position.
559 CalculateListOfExpressionsFingerprint(); // read list of expressions.
560 return;
561 case kIsExpression:
562 ReadPosition(); // read position.
563 CalculateExpressionFingerprint(); // read operand.
564 CalculateDartTypeFingerprint(); // read type.
565 return;
566 case kAsExpression:
567 ReadPosition(); // read position.
568 BuildHash(ReadFlags()); // read flags.
569 CalculateExpressionFingerprint(); // read operand.
570 CalculateDartTypeFingerprint(); // read type.
571 return;
572 case kTypeLiteral:
573 ReadPosition(); // read position.
574 CalculateDartTypeFingerprint(); // read type.
575 return;
576 case kThisExpression:
577 ReadPosition(); // read position.
578 return;
579 case kRethrow:
580 ReadPosition(); // read position.
581 return;
582 case kThrow:
583 ReadPosition(); // read position.
584 BuildHash(ReadFlags()); // read flags.
585 CalculateExpressionFingerprint(); // read expression.
586 return;
587 case kListLiteral:
588 ReadPosition(); // read position.
589 CalculateDartTypeFingerprint(); // read type.
590 CalculateListOfExpressionsFingerprint(); // read list of expressions.
591 return;
592 case kSetLiteral:
593 // Set literals are currently desugared in the frontend and will not
594 // reach the VM. See http://dartbug.com/35124 for discussion.
595 UNREACHABLE();
596 return;
597 case kMapLiteral: {
598 ReadPosition(); // read position.
599 CalculateDartTypeFingerprint(); // read type.
600 CalculateDartTypeFingerprint(); // read value type.
601 intptr_t list_length = ReadListLength(); // read list length.
602 for (intptr_t i = 0; i < list_length; ++i) {
603 CalculateExpressionFingerprint(); // read ith key.
604 CalculateExpressionFingerprint(); // read ith value.
605 }
606 return;
607 }
608 case kRecordLiteral:
609 ReadPosition(); // read position.
610 CalculateListOfExpressionsFingerprint(); // read positionals.
611 CalculateListOfNamedExpressionsFingerprint(); // read named.
612 CalculateDartTypeFingerprint(); // read recordType.
613 return;
614 case kRecordIndexGet:
615 ReadPosition(); // read position.
616 CalculateExpressionFingerprint(); // read receiver.
617 CalculateDartTypeFingerprint(); // read recordType.
618 BuildHash(ReadUInt()); // read index.
619 return;
620 case kRecordNameGet:
621 ReadPosition(); // read position.
622 CalculateExpressionFingerprint(); // read receiver.
623 CalculateDartTypeFingerprint(); // read recordType.
624 CalculateStringReferenceFingerprint(); // read name.
625 return;
626 case kFunctionExpression:
627 ReadPosition(); // read position.
628 CalculateFunctionNodeFingerprint(); // read function node.
629 return;
630 case kLet:
631 ReadPosition(); // read position.
632 CalculateVariableDeclarationFingerprint(); // read variable declaration.
633 CalculateExpressionFingerprint(); // read expression.
634 return;
635 case kBlockExpression:
636 ReadPosition(); // read position.
637 CalculateStatementListFingerprint();
638 CalculateExpressionFingerprint(); // read expression.
639 return;
640 case kInstantiation:
641 ReadPosition(); // read position.
642 CalculateExpressionFingerprint(); // read expression.
643 CalculateListOfDartTypesFingerprint(); // read type arguments.
644 return;
645 case kBigIntLiteral:
646 ReadPosition(); // read position.
647 CalculateStringReferenceFingerprint(); // read string reference.
648 return;
649 case kStringLiteral:
650 ReadPosition(); // read position.
651 CalculateStringReferenceFingerprint(); // read string reference.
652 return;
653 case kSpecializedIntLiteral:
654 ReadPosition(); // read position.
655 return;
656 case kNegativeIntLiteral:
657 ReadPosition(); // read position.
658 BuildHash(ReadUInt()); // read value.
659 return;
660 case kPositiveIntLiteral:
661 ReadPosition(); // read position.
662 BuildHash(ReadUInt()); // read value.
663 return;
664 case kDoubleLiteral: {
665 ReadPosition(); // read position.
666 double value = ReadDouble(); // read value.
667 uint64_t data = bit_cast<uint64_t>(value);
668 BuildHash(static_cast<uint32_t>(data >> 32));
669 BuildHash(static_cast<uint32_t>(data));
670 return;
671 }
672 case kTrueLiteral:
673 ReadPosition(); // read position.
674 return;
675 case kFalseLiteral:
676 ReadPosition(); // read position.
677 return;
678 case kNullLiteral:
679 ReadPosition(); // read position.
680 return;
681 case kConstantExpression:
682 ReadPosition();
683 SkipDartType();
685 return;
686 case kFileUriConstantExpression:
687 ReadPosition();
688 ReadUInt(); // skip uri
689 SkipDartType();
691 return;
692 case kLoadLibrary:
693 case kCheckLibraryIsLoaded:
694 ReadPosition(); // read file offset.
695 ReadUInt(); // skip library index
696 return;
697 case kAwaitExpression:
698 ReadPosition(); // read position.
699 CalculateExpressionFingerprint(); // read operand.
700 if (ReadTag() == kSomething) {
701 CalculateDartTypeFingerprint(); // read runtime check type.
702 }
703 return;
704 case kFileUriExpression:
705 ReadUInt(); // skip uri
706 ReadPosition(); // read position
707 CalculateExpressionFingerprint();
708 return;
709 case kConstStaticInvocation:
710 case kConstConstructorInvocation:
711 case kConstListLiteral:
712 case kConstSetLiteral:
713 case kConstMapLiteral:
714 case kSymbolLiteral:
715 case kListConcatenation:
716 case kSetConcatenation:
717 case kMapConcatenation:
718 case kInstanceCreation:
719 case kStaticTearOff:
720 case kSwitchExpression:
721 case kPatternAssignment:
722 // These nodes are internal to the front end and
723 // removed by the constant evaluator.
724 default:
725 ReportUnexpectedTag("expression", tag);
726 UNREACHABLE();
727 }
728}
729
730void KernelFingerprintHelper::CalculateStatementFingerprint() {
731 Tag tag = ReadTag(); // read tag.
732 BuildHash(tag);
733 switch (tag) {
734 case kExpressionStatement:
735 CalculateExpressionFingerprint(); // read expression.
736 return;
737 case kBlock:
738 ReadPosition(); // read file offset.
739 ReadPosition(); // read file end offset.
740 CalculateStatementListFingerprint();
741 return;
742 case kEmptyStatement:
743 return;
744 case kAssertBlock:
745 CalculateStatementListFingerprint();
746 return;
747 case kAssertStatement:
748 CalculateExpressionFingerprint(); // Read condition.
749 ReadPosition(); // read condition start offset.
750 ReadPosition(); // read condition end offset.
751 if (ReadTag() == kSomething) {
752 CalculateExpressionFingerprint(); // read (rest of) message.
753 }
754 return;
755 case kLabeledStatement:
756 ReadPosition(); // read position.
757 CalculateStatementFingerprint(); // read body.
758 return;
759 case kBreakStatement:
760 ReadPosition(); // read position.
761 ReadUInt(); // read target_index.
762 return;
763 case kWhileStatement:
764 ReadPosition(); // read position.
765 CalculateExpressionFingerprint(); // read condition.
766 CalculateStatementFingerprint(); // read body.
767 return;
768 case kDoStatement:
769 ReadPosition(); // read position.
770 CalculateStatementFingerprint(); // read body.
771 CalculateExpressionFingerprint(); // read condition.
772 return;
773 case kForStatement: {
774 ReadPosition(); // read position.
775 CalculateListOfVariableDeclarationsFingerprint(); // read variables.
776 Tag tag = ReadTag(); // Read first part of condition.
777 if (tag == kSomething) {
778 CalculateExpressionFingerprint(); // read rest of condition.
779 }
780 CalculateListOfExpressionsFingerprint(); // read updates.
781 CalculateStatementFingerprint(); // read body.
782 return;
783 }
784 case kSwitchStatement: {
785 ReadPosition(); // read position.
786 ReadBool(); // read exhaustive flag.
787 CalculateExpressionFingerprint(); // read condition.
788 CalculateOptionalDartTypeFingerprint(); // read expression type
789 int case_count = ReadListLength(); // read number of cases.
790 for (intptr_t i = 0; i < case_count; ++i) {
791 ReadPosition(); // read file offset.
792 int expression_count = ReadListLength(); // read number of expressions.
793 for (intptr_t j = 0; j < expression_count; ++j) {
794 ReadPosition(); // read jth position.
795 CalculateExpressionFingerprint(); // read jth expression.
796 }
797 BuildHash(static_cast<uint32_t>(ReadBool())); // read is_default.
798 CalculateStatementFingerprint(); // read body.
799 }
800 return;
801 }
802 case kContinueSwitchStatement:
803 ReadPosition(); // read position.
804 ReadUInt(); // read target_index.
805 return;
806 case kIfStatement:
807 ReadPosition(); // read position.
808 CalculateExpressionFingerprint(); // read condition.
809 CalculateStatementFingerprint(); // read then.
810 CalculateStatementFingerprint(); // read otherwise.
811 return;
812 case kReturnStatement: {
813 ReadPosition(); // read position
814 Tag tag = ReadTag(); // read (first part of) expression.
815 BuildHash(tag);
816 if (tag == kSomething) {
817 CalculateExpressionFingerprint(); // read (rest of) expression.
818 }
819 return;
820 }
821 case kTryCatch: {
822 ReadPosition(); // read position.
823 CalculateStatementFingerprint(); // read body.
824 BuildHash(ReadByte()); // read flags
825 intptr_t catch_count = ReadListLength(); // read number of catches.
826 for (intptr_t i = 0; i < catch_count; ++i) {
827 ReadPosition(); // read position.
828 CalculateDartTypeFingerprint(); // read guard.
829 tag = ReadTag(); // read first part of exception.
830 BuildHash(tag);
831 if (tag == kSomething) {
832 CalculateVariableDeclarationFingerprint(); // read exception.
833 }
834 tag = ReadTag(); // read first part of stack trace.
835 BuildHash(tag);
836 if (tag == kSomething) {
837 CalculateVariableDeclarationFingerprint(); // read stack trace.
838 }
839 CalculateStatementFingerprint(); // read body.
840 }
841 return;
842 }
843 case kTryFinally:
844 ReadPosition(); // read position.
845 CalculateStatementFingerprint(); // read body.
846 CalculateStatementFingerprint(); // read finalizer.
847 return;
848 case kYieldStatement: {
849 ReadPosition(); // read position.
850 BuildHash(ReadByte()); // read flags.
851 CalculateExpressionFingerprint(); // read expression.
852 return;
853 }
854 case kVariableDeclaration:
855 CalculateVariableDeclarationFingerprint(); // read variable declaration.
856 return;
858 ReadPosition(); // read position.
859 CalculateVariableDeclarationFingerprint(); // read variable.
860 CalculateFunctionNodeFingerprint(); // read function node.
861 return;
862 case kForInStatement:
863 case kAsyncForInStatement:
864 case kIfCaseStatement:
865 case kPatternSwitchStatement:
866 case kPatternVariableDeclaration:
867 // These nodes are internal to the front end and
868 // removed by the constant evaluator.
869 default:
870 ReportUnexpectedTag("statement", tag);
871 UNREACHABLE();
872 }
873}
874
876 hash_ = 0;
877 FieldHelper field_helper(this);
878
880 const String& name = ReadNameAsFieldName(); // read name.
881 field_helper.SetJustRead(FieldHelper::kName);
882
884 CalculateDartTypeFingerprint(); // read type.
885 field_helper.SetJustRead(FieldHelper::kType);
886
887 if (ReadTag() == kSomething) {
888 if (PeekTag() == kFunctionExpression) {
890 CalculateExpressionFingerprint();
891 }
893 }
894
895 BuildHash(name.Hash());
896 BuildHash(field_helper.flags_);
897 BuildHash(field_helper.annotation_count_);
898 return hash_;
899}
900
901void KernelFingerprintHelper::CalculateFunctionNodeFingerprint() {
902 FunctionNodeHelper function_node_helper(this);
903
904 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
905 CalculateTypeParametersListFingerprint();
906 function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
907
908 function_node_helper.ReadUntilExcluding(
910 CalculateListOfVariableDeclarationsFingerprint(); // read positionals
911 CalculateListOfVariableDeclarationsFingerprint(); // read named
912 CalculateDartTypeFingerprint(); // read return type.
913 CalculateOptionalDartTypeFingerprint(); // read emitted value type.
914
915 if (ReadTag() == kSomething) { // read redirecting factory target
916 ReadCanonicalNameReference(); // read member reference
917 if (ReadTag() == kSomething) {
918 SkipListOfDartTypes(); // read type arguments
919 }
920 if (ReadTag() == kSomething) {
921 ReadStringReference(); // read error message
922 }
923 }
924
925 if (ReadTag() == kSomething) {
926 CalculateStatementFingerprint(); // Read body.
927 }
928 BuildHash(function_node_helper.total_parameter_count_);
929 BuildHash(function_node_helper.required_parameter_count_);
930}
931
933 hash_ = 0;
934 Tag tag = PeekTag();
935 if (tag == kField) {
937 } else if (tag == kConstructor) {
938 CalculateConstructorFingerprint();
939 return hash_;
940 }
941 ProcedureHelper procedure_helper(this);
943 const String& name = ReadNameAsMethodName(); // Read name.
944 procedure_helper.SetJustRead(ProcedureHelper::kName);
945
947 CalculateFunctionNodeFingerprint();
948
949 BuildHash(procedure_helper.kind_);
950 BuildHash(procedure_helper.flags_);
951 BuildHash(procedure_helper.annotation_count_);
952 BuildHash(procedure_helper.stub_kind_);
953 BuildHash(name.Hash());
954 return hash_;
955}
956
958 const Class& klass) {
959 Zone* zone = Thread::Current()->zone();
960 String& name = String::Handle(zone, klass.Name());
961 const Array& fields = Array::Handle(zone, klass.fields());
962 const Array& functions = Array::Handle(zone, klass.current_functions());
963 const Array& interfaces = Array::Handle(zone, klass.interfaces());
965
966 uint32_t hash = 0;
968
969 type = klass.super_type();
970 if (!type.IsNull()) {
971 name = type.Name();
973 }
974
975 Field& field = Field::Handle(zone);
976 // Calculate fingerprint for the class fields.
977 for (intptr_t i = 0; i < fields.Length(); ++i) {
978 field ^= fields.At(i);
979 uint32_t fingerprint = CalculateFieldFingerprint(field);
981 }
982
983 // Calculate fingerprint for the class functions.
984 Function& func = Function::Handle(zone);
985 for (intptr_t i = 0; i < functions.Length(); ++i) {
986 func ^= functions.At(i);
987 uint32_t fingerprint = CalculateFunctionFingerprint(func);
989 }
990
991 // Calculate fingerprint for the interfaces.
992 for (intptr_t i = 0; i < interfaces.Length(); ++i) {
993 type ^= interfaces.At(i);
994 name = type.Name();
996 }
997
998 return hash;
999}
1000
1002 const Field& field) {
1003 Thread* thread = Thread::Current();
1004 Zone* zone = thread->zone();
1005 const auto& info = KernelProgramInfo::Handle(zone, field.KernelProgramInfo());
1006
1007 TranslationHelper translation_helper(thread);
1008 translation_helper.InitFromKernelProgramInfo(info);
1009
1011 zone, &translation_helper,
1012 TypedDataView::Handle(zone, field.KernelLibrary()),
1013 field.KernelLibraryOffset());
1014 helper.SetOffset(field.kernel_offset());
1015 return helper.CalculateFieldFingerprint();
1016}
1017
1019 const Function& func) {
1020 Thread* thread = Thread::Current();
1021 Zone* zone = thread->zone();
1022 const auto& info = KernelProgramInfo::Handle(zone, func.KernelProgramInfo());
1023
1024 TranslationHelper translation_helper(thread);
1025 translation_helper.InitFromKernelProgramInfo(info);
1026
1028 zone, &translation_helper,
1030 func.KernelLibraryOffset());
1031 helper.SetOffset(func.kernel_offset());
1032 return helper.CalculateFunctionFingerprint();
1033}
1034
1035} // namespace kernel
1036} // namespace dart
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static uint32_t hash(const SkShaderBase::GradientInfo &v)
#define UNREACHABLE()
Definition: assert.h:248
GLenum type
ObjectPtr At(intptr_t index) const
Definition: object.h:10875
intptr_t Length() const
Definition: object.h:10829
TypePtr super_type() const
Definition: object.h:1431
ArrayPtr interfaces() const
Definition: object.h:1447
ArrayPtr fields() const
Definition: object.h:1615
StringPtr Name() const
Definition: object.cc:2977
ArrayPtr current_functions() const
Definition: object.h:1641
intptr_t kernel_offset() const
Definition: object.h:4495
intptr_t KernelLibraryOffset() const
Definition: object.cc:11912
TypedDataViewPtr KernelLibrary() const
Definition: object.cc:11907
KernelProgramInfoPtr KernelProgramInfo() const
Definition: object.cc:11885
intptr_t KernelLibraryOffset() const
Definition: object.cc:10941
intptr_t kernel_offset() const
Definition: object.h:3550
TypedDataViewPtr KernelLibrary() const
Definition: object.cc:10936
KernelProgramInfoPtr KernelProgramInfo() const
Definition: object.cc:10919
static Object & Handle()
Definition: object.h:407
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static uint32_t CalculateHash(uint32_t current, uint32_t val)
KernelFingerprintHelper(Zone *zone, TranslationHelper *translation_helper, const TypedDataView &data, intptr_t data_program_offset)
Tag ReadTag(uint8_t *payload=nullptr)
virtual void ReportUnexpectedTag(const char *variant, Tag tag)
Tag PeekTag(uint8_t *payload=nullptr)
static uint32_t CalculateFunctionFingerprint(const Function &func)
static uint32_t CalculateFieldFingerprint(const Field &field)
static uint32_t CalculateClassFingerprint(const Class &klass)
void InitFromKernelProgramInfo(const KernelProgramInfo &info)
#define ASSERT(E)
uint8_t value
Definition: dart_vm.cc:33
const char *const name
Nullability
Definition: object.h:1112
const char *const class_name
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65
static int8_t data[kExtLength]
Definition: SkMD5.cpp:130