| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 44bc2f2e6b4a56fad8e89fab7e997e58615f8073..517ed188d89b671d13324ba3f1337f3101eb016c 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1069,7 +1069,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->IsJSGlobalProxy());
|
| + ASSERT(!object->IsAccessCheckNeeded());
|
| if (object->IsString() && key->IsNumber()) {
|
| if (state() == UNINITIALIZED) stub = string_stub();
|
| } else if (object->IsJSObject()) {
|
| @@ -1108,21 +1108,17 @@ static bool LookupForWrite(Handle<JSObject> receiver,
|
| Handle<JSObject> holder = receiver;
|
| receiver->Lookup(*name, lookup);
|
| if (lookup->IsFound()) {
|
| - 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->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) {
|
| + receiver->LocalLookupRealNamedProperty(*name, lookup);
|
| + if (!lookup->IsFound()) return false;
|
| }
|
|
|
| + if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
|
| + if (lookup->holder() == *receiver) return lookup->CanHoldValue(value);
|
| if (lookup->IsPropertyCallbacks()) return true;
|
| - // JSGlobalProxy always goes via the runtime, so it's safe to cache.
|
| + // 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.
|
| 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
|
| @@ -1309,7 +1305,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| Handle<String> name,
|
| Handle<Object> value,
|
| InlineCacheHolderFlag cache_holder) {
|
| - if (object->IsJSGlobalProxy()) return slow_stub();
|
| + if (object->IsAccessCheckNeeded()) return slow_stub();
|
| ASSERT(cache_holder == OWN_MAP);
|
| // This is currently guaranteed by checks in StoreIC::Store.
|
| Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
| @@ -1337,17 +1333,19 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| }
|
| case NORMAL:
|
| if (kind() == Code::KEYED_STORE_IC) break;
|
| - if (receiver->IsGlobalObject()) {
|
| + if (receiver->IsJSGlobalProxy() || 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 = Handle<GlobalObject>::cast(receiver);
|
| + Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
|
| + ? handle(GlobalObject::cast(receiver->GetPrototype()))
|
| + : Handle<GlobalObject>::cast(receiver);
|
| Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
|
| Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
|
| - StoreGlobalStub stub(union_type->IsConstant());
|
| -
|
| + StoreGlobalStub stub(
|
| + union_type->IsConstant(), receiver->IsJSGlobalProxy());
|
| Handle<Code> code = stub.GetCodeCopyFromTemplate(
|
| - isolate(), receiver->map(), *cell);
|
| + isolate(), *global, *cell);
|
| // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
|
| HeapObject::UpdateMapCodeCache(receiver, name, code);
|
| return code;
|
| @@ -1388,7 +1386,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
| }
|
| case INTERCEPTOR:
|
| if (kind() == Code::KEYED_STORE_IC) break;
|
| - ASSERT(HasInterceptorSetter(*receiver));
|
| + ASSERT(HasInterceptorSetter(*holder));
|
| return compiler.CompileStoreInterceptor(receiver, name);
|
| case CONSTANT:
|
| break;
|
| @@ -1684,7 +1682,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
|
| }
|
|
|
| if (use_ic) {
|
| - ASSERT(!object->IsJSGlobalProxy());
|
| + ASSERT(!object->IsAccessCheckNeeded());
|
|
|
| if (object->IsJSObject()) {
|
| Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
|
|