Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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 BuildHash(ReadFlags()); // read flags.
564 CalculateExpressionFingerprint(); // read operand.
565 CalculateDartTypeFingerprint(); // read type.
566 return;
567 case kAsExpression:
568 ReadPosition(); // read position.
569 BuildHash(ReadFlags()); // read flags.
570 CalculateExpressionFingerprint(); // read operand.
571 CalculateDartTypeFingerprint(); // read type.
572 return;
573 case kTypeLiteral:
574 ReadPosition(); // read position.
575 CalculateDartTypeFingerprint(); // read type.
576 return;
577 case kThisExpression:
578 ReadPosition(); // read position.
579 return;
580 case kRethrow:
581 ReadPosition(); // read position.
582 return;
583 case kThrow:
584 ReadPosition(); // read position.
585 BuildHash(ReadFlags()); // read flags.
586 CalculateExpressionFingerprint(); // read expression.
587 return;
588 case kListLiteral:
589 ReadPosition(); // read position.
590 CalculateDartTypeFingerprint(); // read type.
591 CalculateListOfExpressionsFingerprint(); // read list of expressions.
592 return;
593 case kSetLiteral:
594 // Set literals are currently desugared in the frontend and will not
595 // reach the VM. See http://dartbug.com/35124 for discussion.
596 UNREACHABLE();
597 return;
598 case kMapLiteral: {
599 ReadPosition(); // read position.
600 CalculateDartTypeFingerprint(); // read type.
601 CalculateDartTypeFingerprint(); // read value type.
602 intptr_t list_length = ReadListLength(); // read list length.
603 for (intptr_t i = 0; i < list_length; ++i) {
604 CalculateExpressionFingerprint(); // read ith key.
605 CalculateExpressionFingerprint(); // read ith value.
606 }
607 return;
608 }
609 case kRecordLiteral:
610 ReadPosition(); // read position.
611 CalculateListOfExpressionsFingerprint(); // read positionals.
612 CalculateListOfNamedExpressionsFingerprint(); // read named.
613 CalculateDartTypeFingerprint(); // read recordType.
614 return;
615 case kRecordIndexGet:
616 ReadPosition(); // read position.
617 CalculateExpressionFingerprint(); // read receiver.
618 CalculateDartTypeFingerprint(); // read recordType.
619 BuildHash(ReadUInt()); // read index.
620 return;
621 case kRecordNameGet:
622 ReadPosition(); // read position.
623 CalculateExpressionFingerprint(); // read receiver.
624 CalculateDartTypeFingerprint(); // read recordType.
625 CalculateStringReferenceFingerprint(); // read name.
626 return;
627 case kFunctionExpression:
628 ReadPosition(); // read position.
629 CalculateFunctionNodeFingerprint(); // read function node.
630 return;
631 case kLet:
632 ReadPosition(); // read position.
633 CalculateVariableDeclarationFingerprint(); // read variable declaration.
634 CalculateExpressionFingerprint(); // read expression.
635 return;
636 case kBlockExpression:
637 ReadPosition(); // read position.
638 CalculateStatementListFingerprint();
639 CalculateExpressionFingerprint(); // read expression.
640 return;
641 case kInstantiation:
642 ReadPosition(); // read position.
643 CalculateExpressionFingerprint(); // read expression.
644 CalculateListOfDartTypesFingerprint(); // read type arguments.
645 return;
646 case kBigIntLiteral:
647 ReadPosition(); // read position.
648 CalculateStringReferenceFingerprint(); // read string reference.
649 return;
650 case kStringLiteral:
651 ReadPosition(); // read position.
652 CalculateStringReferenceFingerprint(); // read string reference.
653 return;
654 case kSpecializedIntLiteral:
655 ReadPosition(); // read position.
656 return;
657 case kNegativeIntLiteral:
658 ReadPosition(); // read position.
659 BuildHash(ReadUInt()); // read value.
660 return;
661 case kPositiveIntLiteral:
662 ReadPosition(); // read position.
663 BuildHash(ReadUInt()); // read value.
664 return;
665 case kDoubleLiteral: {
666 ReadPosition(); // read position.
667 double value = ReadDouble(); // read value.
668 uint64_t data = bit_cast<uint64_t>(value);
669 BuildHash(static_cast<uint32_t>(data >> 32));
670 BuildHash(static_cast<uint32_t>(data));
671 return;
672 }
673 case kTrueLiteral:
674 ReadPosition(); // read position.
675 return;
676 case kFalseLiteral:
677 ReadPosition(); // read position.
678 return;
679 case kNullLiteral:
680 ReadPosition(); // read position.
681 return;
682 case kConstantExpression:
683 ReadPosition();
684 SkipDartType();
686 return;
687 case kFileUriConstantExpression:
688 ReadPosition();
689 ReadUInt(); // skip uri
690 SkipDartType();
692 return;
693 case kLoadLibrary:
694 case kCheckLibraryIsLoaded:
695 ReadPosition(); // read file offset.
696 ReadUInt(); // skip library index
697 return;
698 case kAwaitExpression:
699 ReadPosition(); // read position.
700 CalculateExpressionFingerprint(); // read operand.
701 if (ReadTag() == kSomething) {
702 CalculateDartTypeFingerprint(); // read runtime check type.
703 }
704 return;
705 case kFileUriExpression:
706 ReadUInt(); // skip uri
707 ReadPosition(); // read position
708 CalculateExpressionFingerprint();
709 return;
710 case kConstStaticInvocation:
711 case kConstConstructorInvocation:
712 case kConstListLiteral:
713 case kConstSetLiteral:
714 case kConstMapLiteral:
715 case kSymbolLiteral:
716 case kListConcatenation:
717 case kSetConcatenation:
718 case kMapConcatenation:
719 case kInstanceCreation:
720 case kStaticTearOff:
721 case kSwitchExpression:
722 case kPatternAssignment:
723 // These nodes are internal to the front end and
724 // removed by the constant evaluator.
725 default:
726 ReportUnexpectedTag("expression", tag);
727 UNREACHABLE();
728 }
729}
730
731void KernelFingerprintHelper::CalculateStatementFingerprint() {
732 Tag tag = ReadTag(); // read tag.
733 BuildHash(tag);
734 switch (tag) {
735 case kExpressionStatement:
736 CalculateExpressionFingerprint(); // read expression.
737 return;
738 case kBlock:
739 ReadPosition(); // read file offset.
740 ReadPosition(); // read file end offset.
741 CalculateStatementListFingerprint();
742 return;
743 case kEmptyStatement:
744 return;
745 case kAssertBlock:
746 CalculateStatementListFingerprint();
747 return;
748 case kAssertStatement:
749 CalculateExpressionFingerprint(); // Read condition.
750 ReadPosition(); // read condition start offset.
751 ReadPosition(); // read condition end offset.
752 if (ReadTag() == kSomething) {
753 CalculateExpressionFingerprint(); // read (rest of) message.
754 }
755 return;
756 case kLabeledStatement:
757 ReadPosition(); // read position.
758 CalculateStatementFingerprint(); // read body.
759 return;
760 case kBreakStatement:
761 ReadPosition(); // read position.
762 ReadUInt(); // read target_index.
763 return;
764 case kWhileStatement:
765 ReadPosition(); // read position.
766 CalculateExpressionFingerprint(); // read condition.
767 CalculateStatementFingerprint(); // read body.
768 return;
769 case kDoStatement:
770 ReadPosition(); // read position.
771 CalculateStatementFingerprint(); // read body.
772 CalculateExpressionFingerprint(); // read condition.
773 return;
774 case kForStatement: {
775 ReadPosition(); // read position.
776 CalculateListOfVariableDeclarationsFingerprint(); // read variables.
777 Tag tag = ReadTag(); // Read first part of condition.
778 if (tag == kSomething) {
779 CalculateExpressionFingerprint(); // read rest of condition.
780 }
781 CalculateListOfExpressionsFingerprint(); // read updates.
782 CalculateStatementFingerprint(); // read body.
783 return;
784 }
785 case kSwitchStatement: {
786 ReadPosition(); // read position.
787 ReadBool(); // read exhaustive flag.
788 CalculateExpressionFingerprint(); // read condition.
789 CalculateOptionalDartTypeFingerprint(); // read expression type
790 int case_count = ReadListLength(); // read number of cases.
791 for (intptr_t i = 0; i < case_count; ++i) {
792 ReadPosition(); // read file offset.
793 int expression_count = ReadListLength(); // read number of expressions.
794 for (intptr_t j = 0; j < expression_count; ++j) {
795 ReadPosition(); // read jth position.
796 CalculateExpressionFingerprint(); // read jth expression.
797 }
798 BuildHash(static_cast<uint32_t>(ReadBool())); // read is_default.
799 CalculateStatementFingerprint(); // read body.
800 }
801 return;
802 }
803 case kContinueSwitchStatement:
804 ReadPosition(); // read position.
805 ReadUInt(); // read target_index.
806 return;
807 case kIfStatement:
808 ReadPosition(); // read position.
809 CalculateExpressionFingerprint(); // read condition.
810 CalculateStatementFingerprint(); // read then.
811 CalculateStatementFingerprint(); // read otherwise.
812 return;
813 case kReturnStatement: {
814 ReadPosition(); // read position
815 Tag tag = ReadTag(); // read (first part of) expression.
816 BuildHash(tag);
817 if (tag == kSomething) {
818 CalculateExpressionFingerprint(); // read (rest of) expression.
819 }
820 return;
821 }
822 case kTryCatch: {
823 ReadPosition(); // read position.
824 CalculateStatementFingerprint(); // read body.
825 BuildHash(ReadByte()); // read flags
826 intptr_t catch_count = ReadListLength(); // read number of catches.
827 for (intptr_t i = 0; i < catch_count; ++i) {
828 ReadPosition(); // read position.
829 CalculateDartTypeFingerprint(); // read guard.
830 tag = ReadTag(); // read first part of exception.
831 BuildHash(tag);
832 if (tag == kSomething) {
833 CalculateVariableDeclarationFingerprint(); // read exception.
834 }
835 tag = ReadTag(); // read first part of stack trace.
836 BuildHash(tag);
837 if (tag == kSomething) {
838 CalculateVariableDeclarationFingerprint(); // read stack trace.
839 }
840 CalculateStatementFingerprint(); // read body.
841 }
842 return;
843 }
844 case kTryFinally:
845 ReadPosition(); // read position.
846 CalculateStatementFingerprint(); // read body.
847 CalculateStatementFingerprint(); // read finalizer.
848 return;
849 case kYieldStatement: {
850 ReadPosition(); // read position.
851 BuildHash(ReadByte()); // read flags.
852 CalculateExpressionFingerprint(); // read expression.
853 return;
854 }
855 case kVariableDeclaration:
856 CalculateVariableDeclarationFingerprint(); // read variable declaration.
857 return;
859 ReadPosition(); // read position.
860 CalculateVariableDeclarationFingerprint(); // read variable.
861 CalculateFunctionNodeFingerprint(); // read function node.
862 return;
863 case kForInStatement:
864 case kAsyncForInStatement:
865 case kIfCaseStatement:
866 case kPatternSwitchStatement:
867 case kPatternVariableDeclaration:
868 // These nodes are internal to the front end and
869 // removed by the constant evaluator.
870 default:
871 ReportUnexpectedTag("statement", tag);
872 UNREACHABLE();
873 }
874}
875
877 hash_ = 0;
878 FieldHelper field_helper(this);
879
881 const String& name = ReadNameAsFieldName(); // read name.
882 field_helper.SetJustRead(FieldHelper::kName);
883
885 CalculateDartTypeFingerprint(); // read type.
886 field_helper.SetJustRead(FieldHelper::kType);
887
888 if (ReadTag() == kSomething) {
889 if (PeekTag() == kFunctionExpression) {
891 CalculateExpressionFingerprint();
892 }
894 }
895
896 BuildHash(name.Hash());
897 BuildHash(field_helper.flags_);
898 BuildHash(field_helper.annotation_count_);
899 return hash_;
900}
901
902void KernelFingerprintHelper::CalculateFunctionNodeFingerprint() {
903 FunctionNodeHelper function_node_helper(this);
904
905 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
906 CalculateTypeParametersListFingerprint();
907 function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
908
909 function_node_helper.ReadUntilExcluding(
911 CalculateListOfVariableDeclarationsFingerprint(); // read positionals
912 CalculateListOfVariableDeclarationsFingerprint(); // read named
913 CalculateDartTypeFingerprint(); // read return type.
914 CalculateOptionalDartTypeFingerprint(); // read emitted value type.
915
916 if (ReadTag() == kSomething) { // read redirecting factory target
917 ReadCanonicalNameReference(); // read member reference
918 if (ReadTag() == kSomething) {
919 SkipListOfDartTypes(); // read type arguments
920 }
921 if (ReadTag() == kSomething) {
922 ReadStringReference(); // read error message
923 }
924 }
925
926 if (ReadTag() == kSomething) {
927 CalculateStatementFingerprint(); // Read body.
928 }
929 BuildHash(function_node_helper.total_parameter_count_);
930 BuildHash(function_node_helper.required_parameter_count_);
931}
932
934 hash_ = 0;
935 Tag tag = PeekTag();
936 if (tag == kField) {
938 } else if (tag == kConstructor) {
939 CalculateConstructorFingerprint();
940 return hash_;
941 }
942 ProcedureHelper procedure_helper(this);
944 const String& name = ReadNameAsMethodName(); // Read name.
945 procedure_helper.SetJustRead(ProcedureHelper::kName);
946
948 CalculateFunctionNodeFingerprint();
949
950 BuildHash(procedure_helper.kind_);
951 BuildHash(procedure_helper.flags_);
952 BuildHash(procedure_helper.annotation_count_);
953 BuildHash(procedure_helper.stub_kind_);
954 BuildHash(name.Hash());
955 return hash_;
956}
957
959 const Class& klass) {
960 Zone* zone = Thread::Current()->zone();
961 String& name = String::Handle(zone, klass.Name());
962 const Array& fields = Array::Handle(zone, klass.fields());
963 const Array& functions = Array::Handle(zone, klass.current_functions());
964 const Array& interfaces = Array::Handle(zone, klass.interfaces());
966
967 uint32_t hash = 0;
969
970 type = klass.super_type();
971 if (!type.IsNull()) {
972 name = type.Name();
974 }
975
976 Field& field = Field::Handle(zone);
977 // Calculate fingerprint for the class fields.
978 for (intptr_t i = 0; i < fields.Length(); ++i) {
979 field ^= fields.At(i);
980 uint32_t fingerprint = CalculateFieldFingerprint(field);
982 }
983
984 // Calculate fingerprint for the class functions.
985 Function& func = Function::Handle(zone);
986 for (intptr_t i = 0; i < functions.Length(); ++i) {
987 func ^= functions.At(i);
988 uint32_t fingerprint = CalculateFunctionFingerprint(func);
990 }
991
992 // Calculate fingerprint for the interfaces.
993 for (intptr_t i = 0; i < interfaces.Length(); ++i) {
994 type ^= interfaces.At(i);
995 name = type.Name();
997 }
998
999 return hash;
1000}
1001
1003 const Field& field) {
1004 Thread* thread = Thread::Current();
1005 Zone* zone = thread->zone();
1006 const auto& info = KernelProgramInfo::Handle(zone, field.KernelProgramInfo());
1007
1008 TranslationHelper translation_helper(thread);
1009 translation_helper.InitFromKernelProgramInfo(info);
1010
1012 zone, &translation_helper,
1013 TypedDataView::Handle(zone, field.KernelLibrary()),
1014 field.KernelLibraryOffset());
1015 helper.SetOffset(field.kernel_offset());
1016 return helper.CalculateFieldFingerprint();
1017}
1018
1020 const Function& func) {
1021 Thread* thread = Thread::Current();
1022 Zone* zone = thread->zone();
1023 const auto& info = KernelProgramInfo::Handle(zone, func.KernelProgramInfo());
1024
1025 TranslationHelper translation_helper(thread);
1026 translation_helper.InitFromKernelProgramInfo(info);
1027
1029 zone, &translation_helper,
1031 func.KernelLibraryOffset());
1032 helper.SetOffset(func.kernel_offset());
1033 return helper.CalculateFunctionFingerprint();
1034}
1035
1036} // namespace kernel
1037} // 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
ObjectPtr At(intptr_t index) const
Definition object.h:10854
intptr_t Length() const
Definition object.h:10808
TypePtr super_type() const
Definition object.h:1433
ArrayPtr interfaces() const
Definition object.h:1449
ArrayPtr fields() const
Definition object.h:1617
StringPtr Name() const
Definition object.cc:3038
ArrayPtr current_functions() const
Definition object.h:1643
intptr_t kernel_offset() const
Definition object.h:4468
intptr_t KernelLibraryOffset() const
Definition object.cc:11963
TypedDataViewPtr KernelLibrary() const
Definition object.cc:11958
KernelProgramInfoPtr KernelProgramInfo() const
Definition object.cc:11936
intptr_t KernelLibraryOffset() const
Definition object.cc:10999
intptr_t kernel_offset() const
Definition object.h:3530
TypedDataViewPtr KernelLibrary() const
Definition object.cc:10994
KernelProgramInfoPtr KernelProgramInfo() const
Definition object.cc:10977
static Object & Handle()
Definition object.h:407
Zone * zone() const
static Thread * Current()
Definition thread.h:361
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
const char *const name
Nullability
Definition object.h:1112
const char *const class_name
static uint32_t Hash(uint32_t key)
static int8_t data[kExtLength]
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
Definition SkMD5.cpp:130