Move BuildCallGetter/BuildCallSetter up in the call chain.

This is a refactoring-only CL and the third one in a series for enabling
inlining of accessors. The goal of this CL is to move the builders for accessors
to the places where we might be able to inline them later, i.e. the VisitFoo and
HandleBar member functions of HGraphBuilder.

Extracted duplicate code into LookupAccessorPair.

Review URL: https://chromiumcodereview.appspot.com/10831047

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12209 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ce23fe97
......@@ -4771,6 +4771,11 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
} else {
#if DEBUG
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
ASSERT(!LookupAccessorPair(map, name, &accessors, &holder));
#endif
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
name,
value,
......@@ -5056,30 +5061,6 @@ HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object,
return BuildStoreNamedField(object, name, value, map, &lookup, true);
}
// Handle a known setter directly in the receiver.
map->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValueFromMap(*map));
Handle<JSObject> holder;
if (!callback->IsAccessorPair()) {
return BuildStoreNamedGeneric(object, name, value);
}
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallSetter(object, value, map, accessors, holder);
}
// Handle a known setter somewhere in the prototype chain.
LookupInPrototypes(map, name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValue());
Handle<JSObject> holder(lookup.holder());
if (!callback->IsAccessorPair()) {
return BuildStoreNamedGeneric(object, name, value);
}
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallSetter(object, value, map, accessors, holder);
}
// No luck, do a generic store.
return BuildStoreNamedGeneric(object, name, value);
}
......@@ -5237,7 +5218,16 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
SmallMapList* types = expr->GetReceiverTypes();
if (expr->IsMonomorphic()) {
Handle<Map> map = types->first();
CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, name, value, map));
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
instr = BuildCallSetter(object, value, map, accessors, holder);
} else {
CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
name,
value,
map));
}
} else if (types != NULL && types->length() > 1) {
HandlePolymorphicStoreNamedField(expr, object, value, types, name);
return;
......@@ -5401,7 +5391,13 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HInstruction* load;
if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first();
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
load = BuildCallGetter(object, map, accessors, holder);
} else {
load = BuildLoadNamedMonomorphic(object, name, prop, map);
}
} else {
load = BuildLoadNamedGeneric(object, name, prop);
}
......@@ -5420,12 +5416,18 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
} else {
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
store = BuildCallSetter(object, instr, map, accessors, holder);
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
instr,
map));
}
}
AddInstruction(store);
// Drop the simulated receiver and value. Return the value.
Drop(2);
......@@ -5671,6 +5673,40 @@ HInstruction* HGraphBuilder::BuildCallGetter(HValue* object,
}
bool HGraphBuilder::LookupAccessorPair(Handle<Map> map,
Handle<String> name,
Handle<AccessorPair>* accessors,
Handle<JSObject>* holder) {
LookupResult lookup(isolate());
// Check for a JavaScript accessor directly in the map.
map->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValueFromMap(*map));
if (!callback->IsAccessorPair()) return false;
*accessors = Handle<AccessorPair>::cast(callback);
*holder = Handle<JSObject>();
return true;
}
// Everything else, e.g. a field, can't be an accessor call.
if (lookup.IsFound()) return false;
// Check for a JavaScript accessor somewhere in the proto chain.
LookupInPrototypes(map, name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValue());
if (!callback->IsAccessorPair()) return false;
*accessors = Handle<AccessorPair>::cast(callback);
*holder = Handle<JSObject>(lookup.holder());
return true;
}
// We haven't found a JavaScript accessor anywhere.
return false;
}
HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
Handle<String> name,
Property* expr,
......@@ -5690,29 +5726,6 @@ HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
return new(zone()) HConstant(function, Representation::Tagged());
}
// Handle a known getter directly in the receiver.
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValueFromMap(*map));
Handle<JSObject> holder;
if (!callback->IsAccessorPair()) {
return BuildLoadNamedGeneric(object, name, expr);
}
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallGetter(object, map, accessors, holder);
}
// Handle a known getter somewhere in the prototype chain.
LookupInPrototypes(map, name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValue());
Handle<JSObject> holder(lookup.holder());
if (!callback->IsAccessorPair()) {
return BuildLoadNamedGeneric(object, name, expr);
}
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallGetter(object, map, accessors, holder);
}
// No luck, do a generic load.
return BuildLoadNamedGeneric(object, name, expr);
}
......@@ -6333,7 +6346,14 @@ void HGraphBuilder::VisitProperty(Property* expr) {
HValue* obj = Pop();
if (expr->IsMonomorphic()) {
instr = BuildLoadNamedMonomorphic(obj, name, expr, types->first());
Handle<Map> map = types->first();
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
instr = BuildCallGetter(obj, map, accessors, holder);
} else {
instr = BuildLoadNamedMonomorphic(obj, name, expr, map);
}
} else if (types != NULL && types->length() > 1) {
AddInstruction(new(zone()) HCheckNonSmi(obj));
HandlePolymorphicLoadNamedField(expr, obj, types, name);
......@@ -7823,7 +7843,13 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
HInstruction* load;
if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first();
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
load = BuildCallGetter(object, map, accessors, holder);
} else {
load = BuildLoadNamedMonomorphic(object, name, prop, map);
}
} else {
load = BuildLoadNamedGeneric(object, name, prop);
}
......@@ -7837,12 +7863,18 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
} else {
Handle<AccessorPair> accessors;
Handle<JSObject> holder;
if (LookupAccessorPair(map, name, &accessors, &holder)) {
store = BuildCallSetter(object, after, map, accessors, holder);
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
after,
map));
}
}
AddInstruction(store);
// Overwrite the receiver in the bailout environment with the result
......
......@@ -1088,21 +1088,6 @@ class HGraphBuilder: public AstVisitor {
HValue* right);
HInstruction* BuildIncrement(bool returns_original_input,
CountOperation* expr);
HLoadNamedField* BuildLoadNamedField(HValue* object,
Handle<Map> map,
LookupResult* result,
bool smi_and_map_check);
HInstruction* BuildLoadNamedGeneric(HValue* object,
Handle<String> name,
Property* expr);
HInstruction* BuildLoadKeyedGeneric(HValue* object, HValue* key);
HInstruction* BuildExternalArrayElementAccess(
HValue* external_elements,
HValue* checked_key,
HValue* val,
HValue* dependency,
ElementsKind elements_kind,
bool is_store);
HInstruction* BuildFastElementAccess(HValue* elements,
HValue* checked_key,
HValue* val,
......@@ -1147,6 +1132,22 @@ class HGraphBuilder: public AstVisitor {
bool is_store,
bool* has_side_effects);
// Tries to find a JavaScript accessor of the given name in the prototype
// chain starting at the given map. Return true iff there is one, including
// the corresponding AccessorPair plus its holder (which could be null when
// the accessor is found directly in the given map).
bool LookupAccessorPair(Handle<Map> map,
Handle<String> name,
Handle<AccessorPair>* accessors,
Handle<JSObject>* holder);
HLoadNamedField* BuildLoadNamedField(HValue* object,
Handle<Map> map,
LookupResult* result,
bool smi_and_map_check);
HInstruction* BuildLoadNamedGeneric(HValue* object,
Handle<String> name,
Property* expr);
HInstruction* BuildCallGetter(HValue* object,
Handle<Map> map,
Handle<AccessorPair> accessors,
......@@ -1155,15 +1156,15 @@ class HGraphBuilder: public AstVisitor {
Handle<String> name,
Property* expr,
Handle<Map> map);
HInstruction* BuildCallSetter(HValue* object,
HValue* value,
Handle<Map> map,
Handle<AccessorPair> accessors,
Handle<JSObject> holder);
HInstruction* BuildStoreNamedMonomorphic(HValue* object,
Handle<String> name,
HValue* value,
Handle<Map> map);
HInstruction* BuildLoadKeyedGeneric(HValue* object, HValue* key);
HInstruction* BuildExternalArrayElementAccess(
HValue* external_elements,
HValue* checked_key,
HValue* val,
HValue* dependency,
ElementsKind elements_kind,
bool is_store);
HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name,
HValue* value,
......@@ -1173,6 +1174,15 @@ class HGraphBuilder: public AstVisitor {
HInstruction* BuildStoreNamedGeneric(HValue* object,
Handle<String> name,
HValue* value);
HInstruction* BuildCallSetter(HValue* object,
HValue* value,
Handle<Map> map,
Handle<AccessorPair> accessors,
Handle<JSObject> holder);
HInstruction* BuildStoreNamedMonomorphic(HValue* object,
Handle<String> name,
HValue* value,
Handle<Map> map);
HInstruction* BuildStoreKeyedGeneric(HValue* object,
HValue* key,
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