Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(605)

Unified Diff: src/stub-cache.cc

Issue 62953007: Handle all object types (minus smi) in load/store ICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed commentsx Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/stub-cache.cc
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 1bc4b1314e79cbff3a4616181ed3f236c5095557..9dc89c2314b55fa552558514163221455f0d09a7 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -102,8 +102,10 @@ Code* StubCache::Set(Name* name, Map* map, Code* code) {
Handle<Code> StubCache::FindIC(Handle<Name> name,
Handle<Map> stub_holder_map,
Code::Kind kind,
- Code::ExtraICState extra_state) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_state);
+ Code::ExtraICState extra_state,
+ InlineCacheHolderFlag cache_holder) {
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
+ kind, extra_state, cache_holder);
Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -111,17 +113,10 @@ Handle<Code> StubCache::FindIC(Handle<Name> name,
}
-Handle<Code> StubCache::FindIC(Handle<Name> name,
- Handle<JSObject> stub_holder,
- Code::Kind kind,
- Code::ExtraICState extra_ic_state) {
- return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state);
-}
-
-
Handle<Code> StubCache::FindHandler(Handle<Name> name,
- Handle<JSObject> receiver,
+ Handle<HeapObject> stub_holder,
Code::Kind kind,
+ InlineCacheHolderFlag cache_holder,
StrictModeFlag strict_mode) {
Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
@@ -129,28 +124,36 @@ Handle<Code> StubCache::FindHandler(Handle<Name> name,
STANDARD_STORE, strict_mode);
}
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::HANDLER, extra_ic_state, Code::NORMAL, kind);
- Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
+ Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind);
+
+ Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
return Handle<Code>::null();
}
-Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver,
+Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
+ Handle<HeapObject> object,
Handle<Code> handler,
- Handle<Name> name,
StrictModeFlag strict_mode) {
Code::Kind kind = handler->handler_kind();
- Handle<Map> map(receiver->map());
- Handle<Code> ic = FindIC(name, map, kind, strict_mode);
+ // Use the same cache holder for the IC as for the handler.
+ InlineCacheHolderFlag cache_holder =
+ Code::ExtractCacheHolderFromFlags(handler->flags());
+ Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
+ isolate(), *object, cache_holder));
+ Handle<Map> stub_holder_map(stub_holder->map());
+ Handle<Code> ic = FindIC(
+ name, stub_holder_map, kind, strict_mode, cache_holder);
if (!ic.is_null()) return ic;
+ Handle<Map> map(object->map());
if (kind == Code::LOAD_IC) {
- LoadStubCompiler ic_compiler(isolate());
+ LoadStubCompiler ic_compiler(isolate(), cache_holder);
ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
} else if (kind == Code::KEYED_LOAD_IC) {
- KeyedLoadStubCompiler ic_compiler(isolate());
+ KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder);
ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
} else if (kind == Code::STORE_IC) {
StoreStubCompiler ic_compiler(isolate(), strict_mode);
@@ -161,13 +164,16 @@ Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver,
ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
}
- HeapObject::UpdateMapCodeCache(receiver, name, ic);
+ HeapObject::UpdateMapCodeCache(stub_holder, name, ic);
return ic;
}
Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
- Handle<JSObject> receiver) {
+ Handle<Object> object) {
+ InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
+ Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
+ isolate(), *object, cache_holder));
// 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
@@ -176,7 +182,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
// specific to the name.
Handle<Name> cache_name = factory()->empty_string();
Handle<JSObject> current;
- Handle<Object> next = receiver;
+ Handle<Object> next = stub_holder;
Handle<JSGlobalObject> global;
do {
current = Handle<JSObject>::cast(next);
@@ -191,13 +197,14 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
// Compile the stub that is either shared for all names or
// name specific if there are global objects involved.
- Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC);
+ Handle<Code> handler = FindHandler(
+ cache_name, stub_holder, Code::LOAD_IC, cache_holder);
if (!handler.is_null()) return handler;
- LoadStubCompiler compiler(isolate_);
+ LoadStubCompiler compiler(isolate_, cache_holder);
handler =
- compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
- HeapObject::UpdateMapCodeCache(receiver, cache_name, handler);
+ compiler.CompileLoadNonexistent(object, current, cache_name, global);
+ HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler);
return handler;
}
@@ -257,9 +264,8 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
Handle<JSObject> holder,
Handle<JSFunction> function) {
// Compute the check type and the map.
- InlineCacheHolderFlag cache_holder =
- IC::GetCodeCacheForObject(*object, *holder);
- Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
+ InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
+ Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
isolate_, *object, cache_holder));
// Compute check type based on receiver/holder.
@@ -283,7 +289,7 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
}
Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, Code::CONSTANT, argc, cache_holder);
+ kind, extra_state, cache_holder, Code::CONSTANT, argc);
Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -312,9 +318,8 @@ Handle<Code> StubCache::ComputeCallField(int argc,
Handle<JSObject> holder,
PropertyIndex index) {
// Compute the check type and the map.
- InlineCacheHolderFlag cache_holder =
- IC::GetCodeCacheForObject(*object, *holder);
- Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
+ InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
+ Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
isolate_, *object, cache_holder));
// TODO(1233596): We cannot do receiver map check for non-JS objects
@@ -326,7 +331,7 @@ Handle<Code> StubCache::ComputeCallField(int argc,
}
Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, Code::FIELD, argc, cache_holder);
+ kind, extra_state, cache_holder, Code::FIELD, argc);
Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -351,9 +356,8 @@ Handle<Code> StubCache::ComputeCallInterceptor(int argc,
Handle<Object> object,
Handle<JSObject> holder) {
// Compute the check type and the map.
- InlineCacheHolderFlag cache_holder =
- IC::GetCodeCacheForObject(*object, *holder);
- Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
+ InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
+ Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
isolate_, *object, cache_holder));
// TODO(1233596): We cannot do receiver map check for non-JS objects
@@ -365,7 +369,7 @@ Handle<Code> StubCache::ComputeCallInterceptor(int argc,
}
Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, Code::INTERCEPTOR, argc, cache_holder);
+ kind, extra_state, cache_holder, Code::INTERCEPTOR, argc);
Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -392,7 +396,7 @@ Handle<Code> StubCache::ComputeCallGlobal(int argc,
Handle<PropertyCell> cell,
Handle<JSFunction> function) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, Code::NORMAL, argc);
+ kind, extra_state, OWN_MAP, Code::NORMAL, argc);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -1096,10 +1100,7 @@ Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
masm_.GetCode(&desc);
Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
#ifdef ENABLE_DISASSEMBLER
- if (FLAG_print_code_stubs) {
- CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
- code->Disassemble(name, trace_scope.file());
- }
+ if (FLAG_print_code_stubs) code->Disassemble(name);
#endif
return code;
}
@@ -1127,55 +1128,82 @@ void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
Register LoadStubCompiler::HandlerFrontendHeader(
- Handle<JSObject> object,
+ Handle<Object> object,
Register object_reg,
Handle<JSObject> holder,
Handle<Name> name,
Label* miss) {
- return CheckPrototypes(object, object_reg, holder,
+ Handle<JSObject> receiver;
+ PrototypeCheckType check_type = CHECK_ALL_MAPS;
+ int function_index = -1;
+ if (object->IsJSObject()) {
+ receiver = Handle<JSObject>::cast(object);
+ check_type = SKIP_RECEIVER;
+ } else {
+ if (object->IsString()) {
+ function_index = Context::STRING_FUNCTION_INDEX;
+ } else if (object->IsSymbol()) {
+ function_index = Context::SYMBOL_FUNCTION_INDEX;
+ } else if (object->IsNumber()) {
+ function_index = Context::NUMBER_FUNCTION_INDEX;
+ } else {
+ ASSERT(object->IsBoolean());
+ // Booleans use the generic oddball map, so an additional check is
+ // needed to ensure the receiver is really a boolean.
+ GenerateBooleanCheck(object_reg, miss);
+ function_index = Context::BOOLEAN_FUNCTION_INDEX;
+ }
+
+ GenerateDirectLoadGlobalFunctionPrototype(
+ masm(), function_index, scratch1(), miss);
+ receiver = handle(JSObject::cast(object->GetPrototype(isolate())));
+ object_reg = scratch1();
+ }
+
+ // Check that the maps starting from the prototype haven't changed.
+ return CheckPrototypes(receiver, object_reg, holder,
scratch1(), scratch2(), scratch3(),
- name, miss, SKIP_RECEIVER);
+ name, miss, check_type);
}
// HandlerFrontend for store uses the name register. It has to be restored
// before a miss.
Register StoreStubCompiler::HandlerFrontendHeader(
- Handle<JSObject> object,
+ Handle<Object> object,
Register object_reg,
Handle<JSObject> holder,
Handle<Name> name,
Label* miss) {
- return CheckPrototypes(object, object_reg, holder,
+ return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder,
this->name(), scratch1(), scratch2(),
name, miss, SKIP_RECEIVER);
}
-Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object,
+Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object,
Register object_reg,
Handle<JSObject> holder,
- Handle<Name> name,
- Label* success) {
+ Handle<Name> name) {
Label miss;
Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
- HandlerFrontendFooter(name, success, &miss);
+ HandlerFrontendFooter(name, &miss);
+
return reg;
}
void LoadStubCompiler::NonexistentHandlerFrontend(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> last,
Handle<Name> name,
- Label* success,
Handle<JSGlobalObject> global) {
Label miss;
- Register holder =
- HandlerFrontendHeader(object, receiver(), last, name, &miss);
+ Register holder = HandlerFrontendHeader(
+ object, receiver(), last, name, &miss);
if (!last->HasFastProperties() &&
!last->IsJSGlobalObject() &&
@@ -1196,12 +1224,12 @@ void LoadStubCompiler::NonexistentHandlerFrontend(
GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
}
- HandlerFrontendFooter(name, success, &miss);
+ HandlerFrontendFooter(name, &miss);
}
Handle<Code> LoadStubCompiler::CompileLoadField(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
PropertyIndex field,
@@ -1221,13 +1249,11 @@ Handle<Code> LoadStubCompiler::CompileLoadField(
Handle<Code> LoadStubCompiler::CompileLoadConstant(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> value) {
- Label success;
- HandlerFrontend(object, receiver(), holder, name, &success);
- __ bind(&success);
+ HandlerFrontend(object, receiver(), holder, name);
GenerateLoadConstant(value);
// Return the generated code.
@@ -1236,15 +1262,12 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(
Handle<Code> LoadStubCompiler::CompileLoadCallback(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
Handle<ExecutableAccessorInfo> callback) {
- Label success;
-
Register reg = CallbackHandlerFrontend(
- object, receiver(), holder, name, &success, callback);
- __ bind(&success);
+ object, receiver(), holder, name, callback);
GenerateLoadCallback(reg, callback);
// Return the generated code.
@@ -1253,17 +1276,13 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<Code> LoadStubCompiler::CompileLoadCallback(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
const CallOptimization& call_optimization) {
ASSERT(call_optimization.is_simple_api_call());
- Label success;
-
Handle<JSFunction> callback = call_optimization.constant_function();
- CallbackHandlerFrontend(
- object, receiver(), holder, name, &success, callback);
- __ bind(&success);
+ CallbackHandlerFrontend(object, receiver(), holder, name, callback);
GenerateLoadCallback(call_optimization);
// Return the generated code.
@@ -1272,16 +1291,13 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name) {
- Label success;
-
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
- Register reg = HandlerFrontend(object, receiver(), holder, name, &success);
- __ bind(&success);
+ Register reg = HandlerFrontend(object, receiver(), holder, name);
// TODO(368): Compile in the whole chain: all the interceptors in
// prototypes and ultimate answer.
GenerateLoadInterceptor(reg, object, holder, &lookup, name);
@@ -1296,7 +1312,6 @@ void LoadStubCompiler::GenerateLoadPostInterceptor(
Handle<JSObject> interceptor_holder,
Handle<Name> name,
LookupResult* lookup) {
- Label success;
Handle<JSObject> holder(lookup->holder());
if (lookup->IsField()) {
PropertyIndex field = lookup->GetFieldIndex();
@@ -1307,8 +1322,7 @@ void LoadStubCompiler::GenerateLoadPostInterceptor(
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
Register reg = HandlerFrontend(
- interceptor_holder, interceptor_reg, holder, name, &success);
- __ bind(&success);
+ interceptor_holder, interceptor_reg, holder, name);
GenerateLoadField(
reg, holder, field, lookup->representation());
}
@@ -1321,8 +1335,7 @@ void LoadStubCompiler::GenerateLoadPostInterceptor(
ASSERT(callback->getter() != NULL);
Register reg = CallbackHandlerFrontend(
- interceptor_holder, interceptor_reg, holder, name, &success, callback);
- __ bind(&success);
+ interceptor_holder, interceptor_reg, holder, name, callback);
GenerateLoadCallback(reg, callback);
}
}
@@ -1342,14 +1355,11 @@ Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
- Handle<JSObject> object,
+ Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
Handle<JSFunction> getter) {
- Label success;
- HandlerFrontend(object, receiver(), holder, name, &success);
-
- __ bind(&success);
+ HandlerFrontend(object, receiver(), holder, name);
GenerateLoadViaGetter(masm(), receiver(), getter);
// Return the generated code.
@@ -1442,10 +1452,7 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
Handle<JSObject> holder,
Handle<Name> name,
Handle<JSFunction> setter) {
- Label success;
- HandlerFrontend(object, receiver(), holder, name, &success);
-
- __ bind(&success);
+ HandlerFrontend(object, receiver(), holder, name);
GenerateStoreViaSetter(masm(), setter);
return GetCode(kind(), Code::CALLBACKS, name);
@@ -1555,7 +1562,7 @@ Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind,
Code::StubType type,
Handle<Name> name) {
Code::Flags flags = Code::ComputeFlags(
- Code::HANDLER, MONOMORPHIC, extra_state(), type, kind);
+ Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
JitEvent(name, code);
@@ -1723,11 +1730,8 @@ Handle<Code> CallStubCompiler::CompileCustomCall(
Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
Handle<Name> name) {
int argc = arguments_.immediate();
- Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
- extra_state_,
- type,
- argc,
- cache_holder_);
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
+ kind_, extra_state_, cache_holder_, type, argc);
return GetCodeWithFlags(flags, name);
}
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698