Revision: 12209
Author: [email protected]
Date: Fri Jul 27 02:43:06 2012
Log: 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
http://code.google.com/p/v8/source/detail?r=12209
Modified:
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Thu Jul 26 23:27:47 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Jul 27 02:43:06 2012
@@ -4771,6 +4771,11 @@
// 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,
@@ -5055,30 +5060,6 @@
// true = needs smi and map check.
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 @@
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 @@
HInstruction* load;
if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first();
- load = BuildLoadNamedMonomorphic(object, name, prop, map);
+ 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);
}
@@ -5421,10 +5417,16 @@
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
} else {
- CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
- name,
- instr,
- map));
+ 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.
@@ -5669,6 +5671,40 @@
AddInstruction(new(zone()) HPushArgument(object));
return new(zone()) HCallConstantFunction(getter, 1);
}
+
+
+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,
@@ -5689,29 +5725,6 @@
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
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 @@
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 @@
HInstruction* load;
if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first();
- load = BuildLoadNamedMonomorphic(object, name, prop, map);
+ 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);
}
@@ -7838,10 +7864,16 @@
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
} else {
- CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
- name,
- after,
- map));
+ 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);
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Thu Jul 26 23:27:47 2012
+++ /branches/bleeding_edge/src/hydrogen.h Fri Jul 27 02:43:06 2012
@@ -1088,21 +1088,6 @@
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 @@
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 @@
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 @@
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);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev