| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 7c156e59d84cfd20a52a8dbf2878b95cf0f3044a..a2b3d73a185961f9eee10e5d3cb6cfa7da243899 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1066,7 +1066,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
|
| maybe_object = LoadIC::Load(object, Handle<String>::cast(key));
|
| if (maybe_object->IsFailure()) return maybe_object;
|
| } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
|
| - ASSERT(!object->IsAccessCheckNeeded());
|
| + ASSERT(!object->IsJSGlobalProxy());
|
| if (object->IsString() && key->IsNumber()) {
|
| if (state() == UNINITIALIZED) stub = string_stub();
|
| } else if (object->IsJSObject()) {
|
| @@ -1105,17 +1105,21 @@ static bool LookupForWrite(Handle<JSObject> receiver,
|
| Handle<JSObject> holder = receiver;
|
| receiver->Lookup(*name, lookup);
|
| if (lookup->IsFound()) {
|
| - if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) {
|
| - receiver->LocalLookupRealNamedProperty(*name, lookup);
|
| - if (!lookup->IsFound()) return false;
|
| + if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
|
| +
|
| + if (lookup->holder() == *receiver) {
|
| + if (lookup->IsInterceptor() && !HasInterceptorSetter(*receiver)) {
|
| + receiver->LocalLookupRealNamedProperty(*name, lookup);
|
| + return lookup->IsFound() &&
|
| + !lookup->IsReadOnly() &&
|
| + lookup->CanHoldValue(value) &&
|
| + lookup->IsCacheable();
|
| + }
|
| + return lookup->CanHoldValue(value);
|
| }
|
|
|
| - if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
|
| - if (lookup->holder() == *receiver) return lookup->CanHoldValue(value);
|
| if (lookup->IsPropertyCallbacks()) return true;
|
| - // JSGlobalProxy either stores on the global object in the prototype, or
|
| - // goes into the runtime if access checks are needed, so this is always
|
| - // safe.
|
| + // JSGlobalProxy always goes via the runtime, so it's safe to cache.
|
| if (receiver->IsJSGlobalProxy()) return true;
|
| // Currently normal holders in the prototype chain are not supported. They
|
| // would require a runtime positive lookup and verification that the details
|
| @@ -1301,7 +1305,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| Handle<String> name,
|
| Handle<Object> value,
|
| InlineCacheHolderFlag cache_holder) {
|
| - if (object->IsAccessCheckNeeded()) return slow_stub();
|
| + if (object->IsJSGlobalProxy()) return slow_stub();
|
| ASSERT(cache_holder == OWN_MAP);
|
| // This is currently guaranteed by checks in StoreIC::Store.
|
| Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
| @@ -1325,19 +1329,17 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| }
|
| case NORMAL:
|
| if (kind() == Code::KEYED_STORE_IC) break;
|
| - if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
|
| + if (receiver->IsGlobalObject()) {
|
| // The stub generated for the global object picks the value directly
|
| // from the property cell. So the property must be directly on the
|
| // global object.
|
| - Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
|
| - ? handle(GlobalObject::cast(receiver->GetPrototype()))
|
| - : Handle<GlobalObject>::cast(receiver);
|
| + Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
|
| Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
|
| Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
|
| - StoreGlobalStub stub(
|
| - union_type->IsConstant(), receiver->IsJSGlobalProxy());
|
| + StoreGlobalStub stub(union_type->IsConstant());
|
| +
|
| Handle<Code> code = stub.GetCodeCopyFromTemplate(
|
| - isolate(), *global, *cell);
|
| + isolate(), receiver->map(), *cell);
|
| // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
|
| HeapObject::UpdateMapCodeCache(receiver, name, code);
|
| return code;
|
| @@ -1378,7 +1380,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| }
|
| case INTERCEPTOR:
|
| if (kind() == Code::KEYED_STORE_IC) break;
|
| - ASSERT(HasInterceptorSetter(*holder));
|
| + ASSERT(HasInterceptorSetter(*receiver));
|
| return compiler.CompileStoreInterceptor(receiver, name);
|
| case CONSTANT:
|
| break;
|
| @@ -1665,7 +1667,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
|
| }
|
|
|
| if (use_ic) {
|
| - ASSERT(!object->IsAccessCheckNeeded());
|
| + ASSERT(!object->IsJSGlobalProxy());
|
|
|
| if (object->IsJSObject()) {
|
| Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
|
|