Commit eaab533f authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Cleanup the double field tracking in Hydrogen.

Use a dedicated BuildLoadNamedField() with PropertyAccessInfo,
similar to BuildStoreNamedField() for optimized graph building,
and a dedicated BuildLoadNamedField() for the code stubs, and
don't depend on FLAG_track_double_fields during code generation.

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/168583006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19411 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c1729e52
...@@ -81,6 +81,11 @@ class CodeStubGraphBuilderBase : public HGraphBuilder { ...@@ -81,6 +81,11 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HContext* context() { return context_; } HContext* context() { return context_; }
Isolate* isolate() { return info_.isolate(); } Isolate* isolate() { return info_.isolate(); }
HLoadNamedField* BuildLoadNamedField(HValue* object,
Representation representation,
int offset,
bool is_inobject);
enum ArgumentClass { enum ArgumentClass {
NONE, NONE,
SINGLE, SINGLE,
...@@ -559,14 +564,32 @@ Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) { ...@@ -559,14 +564,32 @@ Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) {
} }
HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField(
HValue* object,
Representation representation,
int offset,
bool is_inobject) {
HObjectAccess access = is_inobject
? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
: HObjectAccess::ForBackingStoreOffset(offset, representation);
if (representation.IsDouble()) {
// Load the heap number.
object = Add<HLoadNamedField>(
object, static_cast<HValue*>(NULL),
access.WithRepresentation(Representation::Tagged()));
// Load the double value from it.
access = HObjectAccess::ForHeapNumberValue();
}
return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access);
}
template<> template<>
HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
Representation rep = casted_stub()->representation(); return BuildLoadNamedField(GetParameter(0),
int offset = casted_stub()->offset(); casted_stub()->representation(),
HObjectAccess access = casted_stub()->is_inobject() ? casted_stub()->offset(),
HObjectAccess::ForObservableJSObjectOffset(offset, rep) : casted_stub()->is_inobject());
HObjectAccess::ForBackingStoreOffset(offset, rep);
return AddLoadNamedField(GetParameter(0), access);
} }
...@@ -577,12 +600,10 @@ Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { ...@@ -577,12 +600,10 @@ Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
template<> template<>
HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
Representation rep = casted_stub()->representation(); return BuildLoadNamedField(GetParameter(0),
int offset = casted_stub()->offset(); casted_stub()->representation(),
HObjectAccess access = casted_stub()->is_inobject() ? casted_stub()->offset(),
HObjectAccess::ForObservableJSObjectOffset(offset, rep) : casted_stub()->is_inobject());
HObjectAccess::ForBackingStoreOffset(offset, rep);
return AddLoadNamedField(GetParameter(0), access);
} }
......
...@@ -2821,7 +2821,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { ...@@ -2821,7 +2821,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
// No need for a context lookup if the kind_ matches the initial // No need for a context lookup if the kind_ matches the initial
// map, because we can just load the map in that case. // map, because we can just load the map in that case.
HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
return builder()->AddLoadNamedField(constructor_function_, access); return builder()->Add<HLoadNamedField>(
constructor_function_, static_cast<HValue*>(NULL), access);
} }
// TODO(mvstanton): we should always have a constructor function if we // TODO(mvstanton): we should always have a constructor function if we
...@@ -2846,7 +2847,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { ...@@ -2846,7 +2847,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
// Find the map near the constructor function // Find the map near the constructor function
HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
return builder()->AddLoadNamedField(constructor_function_, access); return builder()->Add<HLoadNamedField>(
constructor_function_, static_cast<HValue*>(NULL), access);
} }
...@@ -4889,8 +4891,9 @@ HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { ...@@ -4889,8 +4891,9 @@ HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
HValue* context = environment()->context(); HValue* context = environment()->context();
int length = current_info()->scope()->ContextChainLength(var->scope()); int length = current_info()->scope()->ContextChainLength(var->scope());
while (length-- > 0) { while (length-- > 0) {
context = AddLoadNamedField( context = Add<HLoadNamedField>(
context, HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); context, static_cast<HValue*>(NULL),
HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
} }
return context; return context;
} }
...@@ -5344,6 +5347,24 @@ HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, ...@@ -5344,6 +5347,24 @@ HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
} }
HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
PropertyAccessInfo* info,
HValue* checked_object) {
HObjectAccess access = info->access();
if (access.representation().IsDouble()) {
// Load the heap number.
checked_object = Add<HLoadNamedField>(
checked_object, static_cast<HValue*>(NULL),
access.WithRepresentation(Representation::Tagged()));
checked_object->set_type(HType::HeapNumber());
// Load the double value from it.
access = HObjectAccess::ForHeapNumberValue();
}
return New<HLoadNamedField>(
checked_object, static_cast<HValue*>(NULL), access);
}
HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
PropertyAccessInfo* info, PropertyAccessInfo* info,
HValue* checked_object, HValue* checked_object,
...@@ -5354,7 +5375,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( ...@@ -5354,7 +5375,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
info->map(), info->lookup(), info->name()); info->map(), info->lookup(), info->name());
HStoreNamedField *instr; HStoreNamedField *instr;
if (FLAG_track_double_fields && field_access.representation().IsDouble()) { if (field_access.representation().IsDouble()) {
HObjectAccess heap_number_access = HObjectAccess heap_number_access =
field_access.WithRepresentation(Representation::Tagged()); field_access.WithRepresentation(Representation::Tagged());
if (transition_to_field) { if (transition_to_field) {
...@@ -5615,7 +5636,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( ...@@ -5615,7 +5636,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
if (info->lookup()->IsField()) { if (info->lookup()->IsField()) {
if (info->IsLoad()) { if (info->IsLoad()) {
return BuildLoadNamedField(checked_holder, info->access()); return BuildLoadNamedField(info, checked_holder);
} else { } else {
return BuildStoreNamedField(info, checked_object, value); return BuildStoreNamedField(info, checked_object, value);
} }
...@@ -6186,29 +6207,6 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { ...@@ -6186,29 +6207,6 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
} }
HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
HObjectAccess access) {
if (FLAG_track_double_fields && access.representation().IsDouble()) {
// load the heap number
HLoadNamedField* heap_number = Add<HLoadNamedField>(
object, static_cast<HValue*>(NULL),
access.WithRepresentation(Representation::Tagged()));
heap_number->set_type(HType::HeapNumber());
// load the double value from it
return New<HLoadNamedField>(
heap_number, static_cast<HValue*>(NULL),
HObjectAccess::ForHeapNumberValue());
}
return New<HLoadNamedField>(object, static_cast<HValue*>(NULL), access);
}
HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object,
HObjectAccess access) {
return AddInstruction(BuildLoadNamedField(object, access));
}
HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
if (string->IsConstant()) { if (string->IsConstant()) {
HConstant* c_string = HConstant::cast(string); HConstant* c_string = HConstant::cast(string);
...@@ -6216,9 +6214,10 @@ HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { ...@@ -6216,9 +6214,10 @@ HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
return Add<HConstant>(c_string->StringValue()->map()->instance_type()); return Add<HConstant>(c_string->StringValue()->map()->instance_type());
} }
} }
return AddLoadNamedField( return Add<HLoadNamedField>(
AddLoadNamedField(string, HObjectAccess::ForMap()), Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
HObjectAccess::ForMapInstanceType()); HObjectAccess::ForMap()),
static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType());
} }
...@@ -6229,7 +6228,8 @@ HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { ...@@ -6229,7 +6228,8 @@ HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
return Add<HConstant>(c_string->StringValue()->length()); return Add<HConstant>(c_string->StringValue()->length());
} }
} }
return AddLoadNamedField(string, HObjectAccess::ForStringLength()); return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
HObjectAccess::ForStringLength());
} }
......
...@@ -1398,8 +1398,6 @@ class HGraphBuilder { ...@@ -1398,8 +1398,6 @@ class HGraphBuilder {
PropertyAccessType access_type, PropertyAccessType access_type,
LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE); LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
HInstruction* AddLoadNamedField(HValue* object, HObjectAccess access);
HInstruction* AddLoadStringInstanceType(HValue* string); HInstruction* AddLoadStringInstanceType(HValue* string);
HInstruction* AddLoadStringLength(HValue* string); HInstruction* AddLoadStringLength(HValue* string);
HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) { HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
...@@ -2559,6 +2557,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2559,6 +2557,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
BailoutId return_id, BailoutId return_id,
bool is_uninitialized = false); bool is_uninitialized = false);
HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
HValue* checked_object);
HInstruction* BuildStoreNamedField(PropertyAccessInfo* info, HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
HValue* checked_object, HValue* checked_object,
HValue* value); HValue* value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment