| Index: src/stub-cache.cc
|
| diff --git a/src/stub-cache.cc b/src/stub-cache.cc
|
| index e6722f74cce84cb716cba3fd461ffe2ac1f872e9..16420a5db6bfebbad212bab994b9294ea98a88f4 100644
|
| --- a/src/stub-cache.cc
|
| +++ b/src/stub-cache.cc
|
| @@ -102,7 +102,6 @@ Code* StubCache::Set(String* name, Map* map, Code* code) {
|
|
|
| Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
|
| Handle<JSObject> receiver) {
|
| - ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
|
| // If no global objects are present in the prototype chain, the load
|
| // nonexistent IC stub can be shared for all names for a given map
|
| // and we use the empty string for the map cache in that case. If
|
| @@ -110,12 +109,20 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
|
| // property cells in the stub and therefore the stub will be
|
| // specific to the name.
|
| Handle<String> cache_name = factory()->empty_string();
|
| - if (receiver->IsGlobalObject()) cache_name = name;
|
| - Handle<JSObject> last = receiver;
|
| - while (last->GetPrototype() != heap()->null_value()) {
|
| - last = Handle<JSObject>(JSObject::cast(last->GetPrototype()));
|
| - if (last->IsGlobalObject()) cache_name = name;
|
| - }
|
| + Handle<JSObject> current;
|
| + Handle<Object> next = receiver;
|
| + Handle<GlobalObject> global;
|
| + do {
|
| + current = Handle<JSObject>::cast(next);
|
| + next = Handle<Object>(current->GetPrototype());
|
| + if (current->IsGlobalObject()) {
|
| + global = Handle<GlobalObject>::cast(current);
|
| + cache_name = name;
|
| + } else if (!current->HasFastProperties()) {
|
| + cache_name = name;
|
| + }
|
| + } while (!next->IsNull());
|
| +
|
| // Compile the stub that is either shared for all names or
|
| // name specific if there are global objects involved.
|
| Code::Flags flags =
|
| @@ -126,7 +133,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
|
|
|
| LoadStubCompiler compiler(isolate_);
|
| Handle<Code> code =
|
| - compiler.CompileLoadNonexistent(cache_name, receiver, last);
|
| + compiler.CompileLoadNonexistent(cache_name, receiver, current, global);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
|
| JSObject::UpdateMapCodeCache(receiver, cache_name, code);
|
| @@ -138,9 +145,11 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| PropertyIndex field_index) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -149,7 +158,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
|
| compiler.CompileLoadField(receiver, holder, field_index, name);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -159,10 +168,12 @@ Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
|
| Handle<JSObject> holder,
|
| Handle<AccessorInfo> callback) {
|
| ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -171,7 +182,7 @@ Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
|
| compiler.CompileLoadCallback(name, receiver, holder, callback);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -180,10 +191,12 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> getter) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -192,7 +205,7 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
|
| compiler.CompileLoadViaGetter(name, receiver, holder, getter);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -201,10 +214,12 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> value) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -213,7 +228,7 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
|
| compiler.CompileLoadConstant(receiver, holder, value, name);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -221,10 +236,12 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
|
| Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -233,7 +250,7 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
|
| compiler.CompileLoadInterceptor(receiver, holder, name);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -248,10 +265,12 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
|
| Handle<GlobalObject> holder,
|
| Handle<JSGlobalPropertyCell> cell,
|
| bool is_dont_delete) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -260,7 +279,7 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
|
| compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -269,10 +288,12 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| PropertyIndex field_index) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -281,7 +302,7 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
|
| compiler.CompileLoadField(name, receiver, holder, field_index);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -290,10 +311,12 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> value) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
|
| Code::CONSTANT_FUNCTION);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -302,7 +325,7 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
|
| compiler.CompileLoadConstant(name, receiver, holder, value);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -310,10 +333,12 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
|
| Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -321,7 +346,7 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
|
| Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
| @@ -331,10 +356,12 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder,
|
| Handle<AccessorInfo> callback) {
|
| - ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
|
| + InlineCacheHolderFlag cache_holder =
|
| + IC::GetCodeCacheForObject(*receiver, *holder);
|
| + Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
|
| Code::Flags flags =
|
| Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| + Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
|
| @@ -343,7 +370,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
|
| compiler.CompileLoadCallback(name, receiver, holder, callback);
|
| PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
|
| GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
|
| - JSObject::UpdateMapCodeCache(receiver, name, code);
|
| + JSObject::UpdateMapCodeCache(map_holder, name, code);
|
| return code;
|
| }
|
|
|
|
|