| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 312e30d0261d69c1448e31063f7fd575984103bf..752a7482540b7a4e747429046b847a29453b8989 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -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();
|
| - 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 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
|
| // 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.
|
| @@ -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();
|
| - 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 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
|
| // 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);
|
|
|
|
|