[ VM / Kernel ] Implemented SourceFingerprint for Dart 2.

Change-Id: I567dda75b908895950329447fdf86df0d66b1984
Reviewed-on: https://dart-review.googlesource.com/50380
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2018-04-19 23:48:28 +00:00 committed by commit-bot@chromium.org
parent 859a8748e0
commit cdb4a15732
10 changed files with 1329 additions and 375 deletions

View file

@ -155,7 +155,6 @@ cc/DebuggerAPI_ScriptGetTokenInfo_MultiLineInterpolation: Fail
cc/Debugger_PrintBreakpointsToJSONArray: Fail
cc/Debugger_Rewind_Optimized: SkipSlow
cc/Debugger_SetBreakpointInPartOfLibrary: Crash
cc/FunctionSourceFingerprint: Fail # Issue 30756
cc/IsolateReload_NotTypedefToTypedef: Fail
cc/IsolateReload_TypedefToNotTypedef: Fail
cc/Profiler_BasicSourcePositionOptimized: Skip

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,8 @@
namespace dart {
namespace kernel {
class KernelReaderHelper;
// Helper class that reads a kernel FunctionNode from binary.
//
// Use ReadUntilExcluding to read up to but not including a field.
@ -50,8 +52,8 @@ class FunctionNodeHelper {
kSyncYielding = 4,
};
explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
explicit FunctionNodeHelper(KernelReaderHelper* helper) {
helper_ = helper;
next_read_ = kStart;
}
@ -72,7 +74,7 @@ class FunctionNodeHelper {
intptr_t required_parameter_count_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -93,8 +95,8 @@ class TypeParameterHelper {
kIsGenericCovariantInterface = 1 << 1
};
explicit TypeParameterHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
explicit TypeParameterHelper(KernelReaderHelper* helper) {
helper_ = helper;
next_read_ = kStart;
}
@ -119,7 +121,7 @@ class TypeParameterHelper {
StringIndex name_index_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -151,10 +153,8 @@ class VariableDeclarationHelper {
kIsGenericCovariantInterface = 1 << 6
};
explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kPosition;
}
explicit VariableDeclarationHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kPosition) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -182,7 +182,7 @@ class VariableDeclarationHelper {
StringIndex name_index_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -219,12 +219,12 @@ class FieldHelper {
kIsGenericCovariantInterface = 1 << 7
};
explicit FieldHelper(StreamingFlowGraphBuilder* builder)
: builder_(builder),
explicit FieldHelper(KernelReaderHelper* helper)
: helper_(helper),
next_read_(kStart),
has_function_literal_initializer_(false) {}
FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset);
FieldHelper(KernelReaderHelper* helper, intptr_t offset);
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -260,11 +260,12 @@ class FieldHelper {
TokenPosition position_;
TokenPosition end_position_;
uint8_t flags_;
uint8_t secondary_flags_;
intptr_t source_uri_index_;
intptr_t annotation_count_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
bool has_function_literal_initializer_;
@ -320,10 +321,8 @@ class ProcedureHelper {
kNoSuchMethodForwarder = 1 << 0,
};
explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kStart;
}
explicit ProcedureHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -359,7 +358,7 @@ class ProcedureHelper {
NameIndex forwarding_stub_super_target_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -392,10 +391,8 @@ class ConstructorHelper {
kSynthetic = 1 << 2,
};
explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kStart;
}
explicit ConstructorHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -418,7 +415,7 @@ class ConstructorHelper {
intptr_t annotation_count_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -456,10 +453,8 @@ class ClassHelper {
kIsEnumClass = 2,
};
explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kStart;
}
explicit ClassHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -484,7 +479,7 @@ class ClassHelper {
uint8_t flags_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -518,10 +513,8 @@ class LibraryHelper {
kExternal = 1,
};
explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kFlags;
}
explicit LibraryHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kFlags) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -542,7 +535,7 @@ class LibraryHelper {
intptr_t procedure_count_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -567,10 +560,8 @@ class LibraryDependencyHelper {
Show = 1 << 0,
};
explicit LibraryDependencyHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kFileOffset;
}
explicit LibraryDependencyHelper(KernelReaderHelper* helper)
: helper_(helper), next_read_(kFileOffset) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@ -583,7 +574,7 @@ class LibraryDependencyHelper {
NameIndex target_library_canonical_name_;
private:
StreamingFlowGraphBuilder* builder_;
KernelReaderHelper* helper_;
intptr_t next_read_;
};
@ -792,7 +783,7 @@ class StreamingScopeBuilder {
void EnterScope(intptr_t kernel_offset);
void ExitScope(TokenPosition start_position, TokenPosition end_position);
void ReportUnexpectedTag(const char* variant, Tag tag);
virtual void ReportUnexpectedTag(const char* variant, Tag tag);
// This enum controls which parameters would be marked as requring type
// check on the callee side.
@ -1002,132 +993,56 @@ class StreamingConstantEvaluator {
Instance& result_;
};
class StreamingFlowGraphBuilder {
class KernelReaderHelper {
public:
StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
const TypedData& data,
intptr_t data_program_offset)
: flow_graph_builder_(flow_graph_builder),
translation_helper_(flow_graph_builder->translation_helper_),
zone_(flow_graph_builder->zone_),
reader_(data),
script_(Script::Handle(zone_, parsed_function()->function().script())),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
data_program_offset_(data_program_offset),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
Zone* zone,
const uint8_t* data_buffer,
intptr_t buffer_length,
intptr_t data_program_offset)
: flow_graph_builder_(NULL),
KernelReaderHelper(Zone* zone,
TranslationHelper* translation_helper,
const Script& script,
const TypedData& data,
intptr_t data_program_offset)
: zone_(zone),
translation_helper_(*translation_helper),
zone_(zone),
reader_(data_buffer, buffer_length),
script_(Script::Handle(zone_)),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
data_program_offset_(data_program_offset),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
const Script& script,
Zone* zone,
const TypedData& data,
intptr_t data_program_offset)
: flow_graph_builder_(NULL),
translation_helper_(*translation_helper),
zone_(zone),
reader_(data),
script_(script),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
data_program_offset_(data_program_offset),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
data_program_offset_(data_program_offset) {}
~StreamingFlowGraphBuilder() {}
KernelReaderHelper(Zone* zone,
TranslationHelper* translation_helper,
const uint8_t* data_buffer,
intptr_t buffer_length,
intptr_t data_program_offset)
: zone_(zone),
translation_helper_(*translation_helper),
reader_(data_buffer, buffer_length),
script_(Script::Handle(zone_)),
data_program_offset_(data_program_offset) {}
FlowGraph* BuildGraph(intptr_t kernel_offset);
virtual ~KernelReaderHelper() {}
Fragment BuildStatementAt(intptr_t kernel_offset);
RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
RawObject* EvaluateMetadata(intptr_t kernel_offset);
void CollectTokenPositionsFor(
intptr_t script_index,
intptr_t initial_script_index,
intptr_t kernel_offset,
GrowableArray<intptr_t>* record_token_positions_in,
GrowableArray<intptr_t>* record_yield_positions_in);
intptr_t SourceTableSize();
String& SourceTableUriFor(intptr_t index);
String& GetSourceFor(intptr_t index);
RawTypedData* GetLineStartsFor(intptr_t index);
void SetOffset(intptr_t offset);
// If a 'ParsedFunction' is provided for 'set_forwarding_stub', this method
// will attach the forwarding stub target reference to the parsed function if
// it crosses a procedure node for a concrete forwarding stub.
void ReadUntilFunctionNode(ParsedFunction* set_forwarding_stub = NULL);
intptr_t ReadListLength();
virtual void ReportUnexpectedTag(const char* variant, Tag tag);
void ReportUnexpectedTag(const char* variant, Tag tag);
protected:
const Script& script() const { return script_; }
private:
void LoadAndSetupTypeParameters(ActiveClass* active_class,
const Object& set_on,
intptr_t type_parameter_count,
const Function& parameterized_function);
virtual void set_current_script_id(intptr_t id) {
// Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
USE(id);
}
void DiscoverEnclosingElements(Zone* zone,
const Function& function,
Function* outermost_function);
virtual void RecordYieldPosition(TokenPosition position) {
// Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
USE(position);
}
StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
const Function& function);
virtual void RecordTokenPosition(TokenPosition position) {
// Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
USE(position);
}
bool optimizing();
FlowGraph* BuildGraphOfFieldInitializer();
FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
void SetupDefaultParameterValues();
Fragment BuildFieldInitializer(NameIndex canonical_name);
Fragment BuildInitializers(const Class& parent_class);
FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
FlowGraph* BuildGraphOfFunction(bool constructor);
FlowGraph* BuildGraphOfNoSuchMethodForwarder(
const Function& function,
bool is_implicit_closure_function,
bool throw_no_such_method_error = false);
intptr_t GetOffsetForSourceInfo(intptr_t index);
Fragment BuildExpression(TokenPosition* position = NULL);
Fragment BuildStatement();
intptr_t ReaderOffset();
intptr_t ReaderOffset() const;
void SkipBytes(intptr_t skip);
bool ReadBool();
uint8_t ReadByte();
@ -1168,12 +1083,222 @@ class StreamingFlowGraphBuilder {
void SkipLibraryPart();
void SkipLibraryTypedef();
TokenPosition ReadPosition(bool record = true);
void record_token_position(TokenPosition position);
void record_yield_position(TokenPosition position);
Tag ReadTag(uint8_t* payload = NULL);
Tag PeekTag(uint8_t* payload = NULL);
uint8_t ReadFlags() { return reader_.ReadFlags(); }
Zone* zone_;
TranslationHelper& translation_helper_;
Reader reader_;
const Script& script_;
// Some items like variables are specified in the kernel binary as
// absolute offsets (as in, offsets within the whole kernel program)
// of their declaration nodes. Hence, to cache and/or access them
// uniquely from within a function's kernel data, we need to
// add/subtract the offset of the kernel data in the over all
// kernel program.
intptr_t data_program_offset_;
friend class ClassHelper;
friend class ConstantHelper;
friend class ConstructorHelper;
friend class DirectCallMetadataHelper;
friend class ProcedureAttributesMetadataHelper;
friend class FieldHelper;
friend class FunctionNodeHelper;
friend class InferredTypeMetadataHelper;
friend class KernelLoader;
friend class LibraryDependencyHelper;
friend class LibraryHelper;
friend class MetadataHelper;
friend class ProcedureHelper;
friend class SimpleExpressionConverter;
friend class StreamingConstantEvaluator;
friend class StreamingDartTypeTranslator;
friend class StreamingScopeBuilder;
friend class VariableDeclarationHelper;
friend class TypeParameterHelper;
};
class KernelFingerprintHelper : public KernelReaderHelper {
public:
KernelFingerprintHelper(Zone* zone,
TranslationHelper* translation_helper,
const Script& script,
const TypedData& data,
intptr_t data_program_offset)
: KernelReaderHelper(zone,
translation_helper,
script,
data,
data_program_offset),
hash_(0) {}
virtual ~KernelFingerprintHelper() {}
uint32_t CalculateFieldFingerprint();
uint32_t CalculateFunctionFingerprint();
static uint32_t CalculateHash(uint32_t current, uint32_t val) {
return current * 31 + val;
}
private:
void BuildHash(uint32_t val);
void CalculateConstructorFingerprint();
void CalculateArgumentsFingerprint();
void CalculateVariableDeclarationFingerprint();
void CalculateStatementListFingerprint();
void CalculateListOfExpressionsFingerprint();
void CalculateListOfDartTypesFingerprint();
void CalculateListOfVariableDeclarationsFingerprint();
void CalculateStringReferenceFingerprint();
void CalculateListOfStringsFingerprint();
void CalculateTypeParameterFingerprint();
void CalculateTypeParametersListFingerprint();
void CalculateCanonicalNameFingerprint();
void CalculateInitializerFingerprint();
void CalculateDartTypeFingerprint();
void CalculateOptionalDartTypeFingerprint();
void CalculateInterfaceTypeFingerprint(bool simple);
void CalculateFunctionTypeFingerprint(bool simple);
void CalculateGetterNameFingerprint();
void CalculateSetterNameFingerprint();
void CalculateMethodNameFingerprint();
void CalculateExpressionFingerprint();
void CalculateStatementFingerprint();
void CalculateFunctionNodeFingerprint();
uint32_t hash_;
};
class StreamingFlowGraphBuilder : public KernelReaderHelper {
public:
StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
const TypedData& data,
intptr_t data_program_offset)
: KernelReaderHelper(
flow_graph_builder->zone_,
&flow_graph_builder->translation_helper_,
Script::Handle(
flow_graph_builder->zone_,
flow_graph_builder->parsed_function_->function().script()),
data,
data_program_offset),
flow_graph_builder_(flow_graph_builder),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
Zone* zone,
const uint8_t* data_buffer,
intptr_t buffer_length,
intptr_t data_program_offset)
: KernelReaderHelper(zone,
translation_helper,
data_buffer,
buffer_length,
data_program_offset),
flow_graph_builder_(NULL),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
const Script& script,
Zone* zone,
const TypedData& data,
intptr_t data_program_offset)
: KernelReaderHelper(zone,
translation_helper,
script,
data,
data_program_offset),
flow_graph_builder_(NULL),
constant_evaluator_(this),
type_translator_(this, /* finalize= */ true),
current_script_id_(-1),
record_for_script_id_(-1),
record_token_positions_into_(NULL),
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
virtual ~StreamingFlowGraphBuilder() {}
FlowGraph* BuildGraph(intptr_t kernel_offset);
void ReportUnexpectedTag(const char* variant, Tag tag) override;
Fragment BuildStatementAt(intptr_t kernel_offset);
RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
RawObject* EvaluateMetadata(intptr_t kernel_offset);
void CollectTokenPositionsFor(
intptr_t script_index,
intptr_t initial_script_index,
intptr_t kernel_offset,
GrowableArray<intptr_t>* record_token_positions_in,
GrowableArray<intptr_t>* record_yield_positions_in);
intptr_t SourceTableSize();
String& SourceTableUriFor(intptr_t index);
String& GetSourceFor(intptr_t index);
RawTypedData* GetLineStartsFor(intptr_t index);
// If a 'ParsedFunction' is provided for 'set_forwarding_stub', this method
// will attach the forwarding stub target reference to the parsed function if
// it crosses a procedure node for a concrete forwarding stub.
void ReadUntilFunctionNode(ParsedFunction* set_forwarding_stub = NULL);
enum DispatchCategory { Interface, ViaThis, Closure, DynamicDispatch };
private:
void LoadAndSetupTypeParameters(ActiveClass* active_class,
const Object& set_on,
intptr_t type_parameter_count,
const Function& parameterized_function);
void DiscoverEnclosingElements(Zone* zone,
const Function& function,
Function* outermost_function);
StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
const Function& function);
bool optimizing();
FlowGraph* BuildGraphOfFieldInitializer();
FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
void SetupDefaultParameterValues();
Fragment BuildFieldInitializer(NameIndex canonical_name);
Fragment BuildInitializers(const Class& parent_class);
FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
FlowGraph* BuildGraphOfFunction(bool constructor);
FlowGraph* BuildGraphOfNoSuchMethodForwarder(
const Function& function,
bool is_implicit_closure_function,
bool throw_no_such_method_error = false);
intptr_t GetOffsetForSourceInfo(intptr_t index);
Fragment BuildExpression(TokenPosition* position = NULL);
Fragment BuildStatement();
void loop_depth_inc();
void loop_depth_dec();
intptr_t for_in_depth();
@ -1425,26 +1550,18 @@ class StreamingFlowGraphBuilder {
bool is_closure,
FunctionNodeHelper* function_node_helper);
const Script& script() { return script_; }
void set_current_script_id(intptr_t id) override { current_script_id_ = id; }
void RecordTokenPosition(TokenPosition position) override;
void RecordYieldPosition(TokenPosition position) override;
// Scan through metadata mappings section and cache offsets for recognized
// metadata kinds.
void EnsureMetadataIsScanned();
FlowGraphBuilder* flow_graph_builder_;
TranslationHelper& translation_helper_;
Zone* zone_;
Reader reader_;
const Script& script_;
StreamingConstantEvaluator constant_evaluator_;
StreamingDartTypeTranslator type_translator_;
// Some items like variables are specified in the kernel binary as
// absolute offsets (as in, offsets within the whole kernel program)
// of their declaration nodes. Hence, to cache and/or access them
// uniquely from within a function's kernel data, we need to
// add/subtract the offset of the kernel data in the over all
// kernel program.
intptr_t data_program_offset_;
intptr_t current_script_id_;
intptr_t record_for_script_id_;
GrowableArray<intptr_t>* record_token_positions_into_;
@ -1463,7 +1580,7 @@ class StreamingFlowGraphBuilder {
friend class FunctionNodeHelper;
friend class InferredTypeMetadataHelper;
friend class KernelLoader;
friend class KernelReader;
friend class KernelReaderHelper;
friend class LibraryDependencyHelper;
friend class LibraryHelper;
friend class MetadataHelper;

View file

@ -556,6 +556,10 @@ const String& TranslationHelper::DartGetterName(NameIndex parent,
return name;
}
const String& TranslationHelper::DartFieldName(NameIndex field) {
return DartFieldName(CanonicalNameParent(field), CanonicalNameString(field));
}
const String& TranslationHelper::DartFieldName(NameIndex parent,
StringIndex field) {
String& name = DartString(field);

View file

@ -406,6 +406,7 @@ class TranslationHelper {
const String& DartGetterName(NameIndex getter);
const String& DartGetterName(NameIndex parent, StringIndex getter);
const String& DartFieldName(NameIndex field);
const String& DartFieldName(NameIndex parent, StringIndex field);
const String& DartMethodName(NameIndex method);
@ -672,6 +673,7 @@ class BaseFlowGraphBuilder {
intptr_t pending_argument_count_;
friend class TryCatchBlock;
friend class KernelReaderHelper;
friend class StreamingFlowGraphBuilder;
friend class FlowGraphBuilder;
friend class PrologueBuilder;
@ -891,6 +893,7 @@ class FlowGraphBuilder : public BaseFlowGraphBuilder {
friend class BreakableBlock;
friend class CatchBlock;
friend class ConstantEvaluator;
friend class KernelReaderHelper;
friend class StreamingFlowGraphBuilder;
friend class ScopeBuilder;
friend class SwitchBlock;

View file

@ -1280,6 +1280,11 @@ void IsolateReloadContext::VerifyMaps() {
static void RecordChanges(const GrowableObjectArray& changed_in_last_reload,
const Class& old_cls,
const Class& new_cls) {
// All members of enum classes are synthetic, so nothing to report here.
if (new_cls.is_enum_class()) {
return;
}
// Don't report synthetic classes like the superclass of
// `class MA extends S with M {}` or `class MA = S with M'. The relevant
// changes with be reported as changes in M.

View file

@ -29,6 +29,95 @@ bool FieldHasFunctionLiteralInitializer(const Field& field,
return field_helper.FieldHasFunctionLiteralInitializer(start, end);
}
uint32_t KernelSourceFingerprintHelper::CalculateClassFingerprint(
const Class& klass) {
Zone* zone = Thread::Current()->zone();
// Handle typedefs.
if (klass.IsTypedefClass()) {
const Function& func = Function::Handle(zone, klass.signature_function());
return CalculateFunctionFingerprint(func);
}
String& name = String::Handle(zone, klass.Name());
const Array& fields = Array::Handle(zone, klass.fields());
const Array& functions = Array::Handle(zone, klass.functions());
const Array& interfaces = Array::Handle(zone, klass.interfaces());
AbstractType& type = AbstractType::Handle(zone);
uint32_t hash = 0;
hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
type ^= klass.super_type();
if (!type.IsNull()) {
name ^= type.Name();
hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
}
type ^= klass.mixin();
if (!type.IsNull()) {
name ^= type.Name();
hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
}
Field& field = Field::Handle(zone);
// Calculate fingerprint for the class fields.
for (intptr_t i = 0; i < fields.Length(); ++i) {
field ^= fields.At(i);
uint32_t fingerprint = CalculateFieldFingerprint(field);
hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
}
// Calculate fingerprint for the class functions.
Function& func = Function::Handle(zone);
for (intptr_t i = 0; i < functions.Length(); ++i) {
func ^= functions.At(i);
uint32_t fingerprint = CalculateFunctionFingerprint(func);
hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
}
// Calculate fingerprint for the interfaces.
for (intptr_t i = 0; i < interfaces.Length(); ++i) {
type ^= interfaces.At(i);
name ^= type.Name();
hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
}
return hash;
}
uint32_t KernelSourceFingerprintHelper::CalculateFieldFingerprint(
const Field& field) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Script& script = Script::Handle(zone, field.Script());
TranslationHelper translation_helper(thread);
translation_helper.InitFromScript(script);
KernelFingerprintHelper helper(zone, &translation_helper, script,
TypedData::Handle(zone, field.KernelData()),
field.KernelDataProgramOffset());
helper.SetOffset(field.kernel_offset());
return helper.CalculateFieldFingerprint();
}
uint32_t KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
const Function& func) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Script& script = Script::Handle(zone, func.script());
TranslationHelper translation_helper(thread);
translation_helper.InitFromScript(script);
KernelFingerprintHelper helper(zone, &translation_helper, script,
TypedData::Handle(zone, func.KernelData()),
func.KernelDataProgramOffset());
helper.SetOffset(func.kernel_offset());
return helper.CalculateFunctionFingerprint();
}
KernelLineStartsReader::KernelLineStartsReader(
const dart::TypedData& line_starts_data,
dart::Zone* zone)

View file

@ -123,6 +123,13 @@ class Program {
DISALLOW_COPY_AND_ASSIGN(Program);
};
class KernelSourceFingerprintHelper {
public:
static uint32_t CalculateClassFingerprint(const Class& klass);
static uint32_t CalculateFieldFingerprint(const Field& field);
static uint32_t CalculateFunctionFingerprint(const Function& func);
};
class KernelLineStartsReader {
public:
KernelLineStartsReader(const dart::TypedData& line_starts_data,

View file

@ -315,16 +315,16 @@ class Reader : public ValueObject {
// the root name as in the canonical name table.
NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); }
intptr_t offset() { return offset_; }
intptr_t offset() const { return offset_; }
void set_offset(intptr_t offset) { offset_ = offset; }
intptr_t size() { return size_; }
intptr_t size() const { return size_; }
void set_size(intptr_t size) { size_ = size; }
const TypedData* typed_data() { return typed_data_; }
const TypedData* typed_data() const { return typed_data_; }
void set_typed_data(const TypedData* typed_data) { typed_data_ = typed_data; }
const uint8_t* raw_buffer() { return raw_buffer_; }
const uint8_t* raw_buffer() const { return raw_buffer_; }
void set_raw_buffer(const uint8_t* raw_buffer) { raw_buffer_ = raw_buffer; }
void CopyDataToVMHeap(const TypedData& typed_data,

View file

@ -3718,8 +3718,16 @@ TokenPosition Class::ComputeEndTokenPos() const {
}
int32_t Class::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
if (kernel_offset() > 0) {
return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint(
*this);
}
return Script::Handle(script()).SourceFingerprint(token_pos(),
ComputeEndTokenPos());
#else
return 0;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
void Class::set_is_implemented() const {
@ -7926,8 +7934,16 @@ RawString* Function::GetSource() const {
// Construct fingerprint from token stream. The token stream contains also
// arguments.
int32_t Function::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
if (kernel_offset() > 0) {
return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
*this);
}
return Script::Handle(script()).SourceFingerprint(token_pos(),
end_token_pos());
#else
return 0;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
void Function::SaveICDataMap(
@ -8478,8 +8494,16 @@ RawField* Field::Clone(const Field& original) const {
}
int32_t Field::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
if (kernel_offset() > 0) {
return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint(
*this);
}
return Script::Handle(Script()).SourceFingerprint(token_pos(),
end_token_pos());
#else
return 0;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
RawString* Field::InitializingExpression() const {