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

Unified Diff: src/stub-cache.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 10 months 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/sweeper-thread.h » ('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 7cb02f6a241f97bbe24bdd4b3c4d61798a32244c..f23e5aaeb355d167790e6a22369d5b2b80db23ff 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -116,9 +116,9 @@ Handle<Code> StubCache::FindIC(Handle<Name> name,
Handle<Code> StubCache::FindHandler(Handle<Name> name,
Handle<Map> stub_holder,
Code::Kind kind,
- InlineCacheHolderFlag cache_holder) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind);
+ InlineCacheHolderFlag cache_holder,
+ Code::StubType type) {
+ Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -127,11 +127,11 @@ Handle<Code> StubCache::FindHandler(Handle<Name> name,
Handle<Code> StubCache::ComputeMonomorphicIC(
+ Code::Kind kind,
Handle<Name> name,
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<Code> handler,
ExtraICState extra_ic_state) {
- Code::Kind kind = handler->handler_kind();
InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
Handle<Map> stub_holder;
@@ -139,7 +139,7 @@ Handle<Code> StubCache::ComputeMonomorphicIC(
// There are multiple string maps that all use the same prototype. That
// prototype cannot hold multiple handlers, one for each of the string maps,
// for a single name. Hence, turn off caching of the IC.
- bool can_be_cached = !type->Is(Type::String());
+ bool can_be_cached = !type->Is(HeapType::String());
if (can_be_cached) {
stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
ic = FindIC(name, stub_holder, kind, extra_ic_state, flag);
@@ -169,7 +169,7 @@ Handle<Code> StubCache::ComputeMonomorphicIC(
Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
- Handle<Type> type) {
+ Handle<HeapType> type) {
InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
// If no dictionary mode objects are present in the prototype chain, the load
@@ -192,10 +192,12 @@ 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, stub_holder, Code::LOAD_IC, flag);
- if (!handler.is_null()) return handler;
+ cache_name, stub_holder, Code::LOAD_IC, flag, Code::FAST);
+ if (!handler.is_null()) {
+ return handler;
+ }
- LoadStubCompiler compiler(isolate_, flag);
+ LoadStubCompiler compiler(isolate_, kNoExtraICState, flag);
handler = compiler.CompileLoadNonexistent(type, last, cache_name);
Map::UpdateCodeCache(stub_holder, cache_name, handler);
return handler;
@@ -247,163 +249,7 @@ Handle<Code> StubCache::ComputeKeyedStoreElement(
}
-#define CALL_LOGGER_TAG(kind, type) \
- (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
-
-Handle<Code> StubCache::ComputeCallConstant(int argc,
- Code::Kind kind,
- ExtraICState extra_state,
- Handle<Name> name,
- Handle<Object> object,
- Handle<JSObject> holder,
- Handle<JSFunction> function) {
- // Compute the check type and the map.
- InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
- Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
- isolate_, *object, cache_holder));
-
- // Compute check type based on receiver/holder.
- CheckType check = RECEIVER_MAP_CHECK;
- if (object->IsString()) {
- check = STRING_CHECK;
- } else if (object->IsSymbol()) {
- check = SYMBOL_CHECK;
- } else if (object->IsNumber()) {
- check = NUMBER_CHECK;
- } else if (object->IsBoolean()) {
- check = BOOLEAN_CHECK;
- }
-
- if (check != RECEIVER_MAP_CHECK &&
- !function->IsBuiltin() &&
- function->shared()->is_classic_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
- return Handle<Code>::null();
- }
-
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, cache_holder, Code::FAST, argc);
- Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
- isolate_);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
- Handle<Code> code =
- compiler.CompileCallConstant(object, holder, name, check, function);
- code->set_check_type(check);
- ASSERT(flags == code->flags());
- PROFILE(isolate_,
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
- GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
-
- HeapObject::UpdateMapCodeCache(stub_holder, name, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallField(int argc,
- Code::Kind kind,
- ExtraICState extra_state,
- Handle<Name> name,
- Handle<Object> object,
- Handle<JSObject> holder,
- PropertyIndex index) {
- // Compute the check type and the map.
- 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
- // because they may be represented as immediates without a
- // map. Instead, we check against the map in the holder.
- if (object->IsNumber() || object->IsSymbol() ||
- object->IsBoolean() || object->IsString()) {
- object = holder;
- }
-
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, cache_holder, Code::FAST, argc);
- Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
- isolate_);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
- Handle<Code> code =
- compiler.CompileCallField(Handle<JSObject>::cast(object),
- holder, index, name);
- ASSERT(flags == code->flags());
- PROFILE(isolate_,
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
- GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
- HeapObject::UpdateMapCodeCache(stub_holder, name, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallInterceptor(int argc,
- Code::Kind kind,
- ExtraICState extra_state,
- Handle<Name> name,
- Handle<Object> object,
- Handle<JSObject> holder) {
- // Compute the check type and the map.
- 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
- // because they may be represented as immediates without a
- // map. Instead, we check against the map in the holder.
- if (object->IsNumber() || object->IsSymbol() ||
- object->IsBoolean() || object->IsString()) {
- object = holder;
- }
-
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, cache_holder, Code::FAST, argc);
- Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
- isolate_);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
- Handle<Code> code =
- compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
- holder, name);
- ASSERT(flags == code->flags());
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
- GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
- HeapObject::UpdateMapCodeCache(stub_holder, name, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallGlobal(int argc,
- Code::Kind kind,
- ExtraICState extra_state,
- Handle<Name> name,
- Handle<JSObject> receiver,
- Handle<GlobalObject> holder,
- Handle<PropertyCell> cell,
- Handle<JSFunction> function) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- 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);
-
- CallStubCompiler compiler(isolate(), argc, kind, extra_state);
- Handle<Code> code =
- compiler.CompileCallGlobal(receiver, holder, cell, function, name);
- ASSERT(flags == code->flags());
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
- GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
- HeapObject::UpdateMapCodeCache(receiver, name, code);
- return code;
-}
-
+#define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
static void FillCache(Isolate* isolate, Handle<Code> code) {
Handle<UnseededNumberDictionary> dictionary =
@@ -414,20 +260,6 @@ static void FillCache(Isolate* isolate, Handle<Code> code) {
}
-Code* StubCache::FindCallInitialize(int argc, Code::Kind kind) {
- Code::Flags flags = Code::ComputeFlags(
- kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
- UnseededNumberDictionary* dictionary =
- isolate()->heap()->non_monomorphic_cache();
- int entry = dictionary->FindEntry(isolate(), flags);
- ASSERT(entry != -1);
- Object* code = dictionary->ValueAt(entry);
- // This might be called during the marking phase of the collector
- // hence the unchecked cast.
- return reinterpret_cast<Code*>(code);
-}
-
-
Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) {
Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
UnseededNumberDictionary* dictionary =
@@ -441,101 +273,6 @@ Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) {
}
-Handle<Code> StubCache::ComputeCallInitialize(int argc, Code::Kind kind) {
- Code::Flags flags = Code::ComputeFlags(
- kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallInitialize(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallInitialize(int argc) {
- return ComputeCallInitialize(argc, Code::CALL_IC);
-}
-
-
-Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
- return ComputeCallInitialize(argc, Code::KEYED_CALL_IC);
-}
-
-
-Handle<Code> StubCache::ComputeCallPreMonomorphic(
- int argc,
- Code::Kind kind,
- ExtraICState extra_state) {
- Code::Flags flags =
- Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallNormal(int argc,
- Code::Kind kind,
- ExtraICState extra_state) {
- Code::Flags flags =
- Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallNormal(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallArguments(int argc) {
- Code::Flags flags =
- Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC,
- kNoExtraICState, Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallArguments(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallMegamorphic(
- int argc,
- Code::Kind kind,
- ExtraICState extra_state) {
- Code::Flags flags =
- Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
- Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallMegamorphic(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state,
ExtraICState extra_state) {
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
@@ -587,26 +324,6 @@ Handle<Code> StubCache::ComputeStore(InlineCacheState ic_state,
}
-Handle<Code> StubCache::ComputeCallMiss(int argc,
- Code::Kind kind,
- ExtraICState extra_state) {
- // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
- // and monomorphic stubs are not mixed up together in the stub cache.
- Code::Flags flags =
- Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
- Code::NORMAL, argc, OWN_MAP);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallMiss(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
CompareNilICStub& stub) {
Handle<String> name(isolate_->heap()->empty_string());
@@ -638,7 +355,7 @@ Handle<Code> StubCache::ComputeLoadElementPolymorphic(
TypeHandleList types(receiver_maps->length());
for (int i = 0; i < receiver_maps->length(); i++) {
- types.Add(Type::Class(receiver_maps->at(i), isolate()));
+ types.Add(HeapType::Class(receiver_maps->at(i), isolate()));
}
CodeHandleList handlers(receiver_maps->length());
KeyedLoadStubCompiler compiler(isolate_);
@@ -654,14 +371,13 @@ Handle<Code> StubCache::ComputeLoadElementPolymorphic(
Handle<Code> StubCache::ComputePolymorphicIC(
+ Code::Kind kind,
TypeHandleList* types,
CodeHandleList* handlers,
int number_of_valid_types,
Handle<Name> name,
ExtraICState extra_ic_state) {
-
Handle<Code> handler = handlers->at(0);
- Code::Kind kind = handler->handler_kind();
Code::StubType type = number_of_valid_types == 1 ? handler->type()
: Code::NORMAL;
if (kind == Code::LOAD_IC) {
@@ -701,46 +417,6 @@ Handle<Code> StubCache::ComputeStoreElementPolymorphic(
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
-Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
- Code::Kind kind) {
- // Extra IC state is irrelevant for debug break ICs. They jump to
- // the actual call ic to carry out the work.
- Code::Flags flags =
- Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_BREAK,
- Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallDebugBreak(flags);
- FillCache(isolate_, code);
- return code;
-}
-
-
-Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
- Code::Kind kind) {
- // Extra IC state is irrelevant for debug break ICs. They jump to
- // the actual call ic to carry out the work.
- Code::Flags flags =
- Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_PREPARE_STEP_IN,
- Code::NORMAL, argc);
- Handle<UnseededNumberDictionary> cache =
- isolate_->factory()->non_monomorphic_cache();
- int entry = cache->FindEntry(isolate_, flags);
- if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
-
- StubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
- FillCache(isolate_, code);
- return code;
-}
-#endif
-
-
void StubCache::Clear() {
Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
for (int i = 0; i < kPrimaryTableSize; i++) {
@@ -994,83 +670,6 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
}
-Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- if (kind == Code::CALL_IC) {
- CallIC::GenerateInitialize(masm(), argc, extra_state);
- } else {
- KeyedCallIC::GenerateInitialize(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize");
- isolate()->counters()->call_initialize_stubs()->Increment();
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
- return code;
-}
-
-
-Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- // The code of the PreMonomorphic stub is the same as the code
- // of the Initialized stub. They just differ on the code object flags.
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- if (kind == Code::CALL_IC) {
- CallIC::GenerateInitialize(masm(), argc, extra_state);
- } else {
- KeyedCallIC::GenerateInitialize(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
- isolate()->counters()->call_premonomorphic_stubs()->Increment();
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
- return code;
-}
-
-
-Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- if (kind == Code::CALL_IC) {
- CallIC::GenerateNormal(masm(), argc);
- } else {
- KeyedCallIC::GenerateNormal(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
- isolate()->counters()->call_normal_stubs()->Increment();
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
- return code;
-}
-
-
-Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- if (kind == Code::CALL_IC) {
- CallIC::GenerateMegamorphic(masm(), argc, extra_state);
- } else {
- KeyedCallIC::GenerateMegamorphic(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
- isolate()->counters()->call_megamorphic_stubs()->Increment();
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
- return code;
-}
-
-
Handle<Code> StubCompiler::CompileLoadInitialize(Code::Flags flags) {
LoadIC::GenerateInitialize(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
@@ -1092,9 +691,7 @@ Handle<Code> StubCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) {
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- ContextualMode mode = LoadIC::GetContextualMode(extra_state);
- LoadIC::GenerateMegamorphic(masm(), mode);
+ LoadIC::GenerateMegamorphic(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
PROFILE(isolate(),
CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
@@ -1136,8 +733,7 @@ Handle<Code> StubCompiler::CompileStoreGeneric(Code::Flags flags) {
Handle<Code> StubCompiler::CompileStoreMegamorphic(Code::Flags flags) {
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- StoreIC::GenerateMegamorphic(masm(), extra_state);
+ StoreIC::GenerateMegamorphic(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
PROFILE(isolate(),
CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
@@ -1146,71 +742,6 @@ Handle<Code> StubCompiler::CompileStoreMegamorphic(Code::Flags flags) {
}
-Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
- CALL_MEGAMORPHIC_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
- return code;
-}
-
-
-Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
- if (kind == Code::CALL_IC) {
- CallIC::GenerateMiss(masm(), argc, extra_state);
- } else {
- KeyedCallIC::GenerateMiss(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss");
- isolate()->counters()->call_megamorphic_stubs()->Increment();
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
- *code, code->arguments_count()));
- GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
- return code;
-}
-
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
- Debug::GenerateCallICDebugBreak(masm());
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
- PROFILE(isolate(),
- CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
- CALL_DEBUG_BREAK_TAG),
- *code, code->arguments_count()));
- return code;
-}
-
-
-Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
- // Use the same code for the the step in preparations as we do for the
- // miss case.
- int argc = Code::ExtractArgumentsCountFromFlags(flags);
- Code::Kind kind = Code::ExtractKindFromFlags(flags);
- if (kind == Code::CALL_IC) {
- // For the debugger extra ic state is irrelevant.
- CallIC::GenerateMiss(masm(), argc, kNoExtraICState);
- } else {
- KeyedCallIC::GenerateMiss(masm(), argc);
- }
- Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
- PROFILE(isolate(),
- CodeCreateEvent(
- CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
- *code,
- code->arguments_count()));
- return code;
-}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
#undef CALL_LOGGER_TAG
@@ -1251,77 +782,21 @@ void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
#define __ ACCESS_MASM(masm())
-void CallStubCompiler::HandlerFrontendFooter(Label* miss) {
- __ bind(miss);
- GenerateMissBranch();
-}
-
-
-void CallStubCompiler::GenerateJumpFunctionIgnoreReceiver(
- Handle<JSFunction> function) {
- ParameterCount expected(function);
- __ InvokeFunction(function, expected, arguments(),
- JUMP_FUNCTION, NullCallWrapper());
-}
-
-
-void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
- Handle<JSFunction> function) {
- PatchImplicitReceiver(object);
- GenerateJumpFunctionIgnoreReceiver(function);
-}
-
-
-void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
- Register actual_closure,
- Handle<JSFunction> function) {
- PatchImplicitReceiver(object);
- ParameterCount expected(function);
- __ InvokeFunction(actual_closure, expected, arguments(),
- JUMP_FUNCTION, NullCallWrapper());
-}
-
-
-Handle<Code> CallStubCompiler::CompileCallConstant(
- Handle<Object> object,
- Handle<JSObject> holder,
- Handle<Name> name,
- CheckType check,
- Handle<JSFunction> function) {
- if (HasCustomCallGenerator(function)) {
- Handle<Code> code = CompileCustomCall(object, holder,
- Handle<Cell>::null(),
- function, Handle<String>::cast(name),
- Code::FAST);
- // A null handle means bail out to the regular compiler code below.
- if (!code.is_null()) return code;
- }
-
- Label miss;
- HandlerFrontendHeader(object, holder, name, check, &miss);
- GenerateJumpFunction(object, function);
- HandlerFrontendFooter(&miss);
-
- // Return the generated code.
- return GetCode(function);
-}
-
-
Register LoadStubCompiler::HandlerFrontendHeader(
- Handle<Type> type,
+ Handle<HeapType> type,
Register object_reg,
Handle<JSObject> holder,
Handle<Name> name,
Label* miss) {
PrototypeCheckType check_type = CHECK_ALL_MAPS;
int function_index = -1;
- if (type->Is(Type::String())) {
+ if (type->Is(HeapType::String())) {
function_index = Context::STRING_FUNCTION_INDEX;
- } else if (type->Is(Type::Symbol())) {
+ } else if (type->Is(HeapType::Symbol())) {
function_index = Context::SYMBOL_FUNCTION_INDEX;
- } else if (type->Is(Type::Number())) {
+ } else if (type->Is(HeapType::Number())) {
function_index = Context::NUMBER_FUNCTION_INDEX;
- } else if (type->Is(Type::Boolean())) {
+ } else if (type->Is(HeapType::Boolean())) {
// Booleans use the generic oddball map, so an additional check is needed to
// ensure the receiver is really a boolean.
GenerateBooleanCheck(object_reg, miss);
@@ -1349,7 +824,7 @@ Register LoadStubCompiler::HandlerFrontendHeader(
// HandlerFrontend for store uses the name register. It has to be restored
// before a miss.
Register StoreStubCompiler::HandlerFrontendHeader(
- Handle<Type> type,
+ Handle<HeapType> type,
Register object_reg,
Handle<JSObject> holder,
Handle<Name> name,
@@ -1361,13 +836,13 @@ Register StoreStubCompiler::HandlerFrontendHeader(
bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
for (int i = 0; i < types->length(); ++i) {
- if (types->at(i)->Is(Type::Number())) return true;
+ if (types->at(i)->Is(HeapType::Number())) return true;
}
return false;
}
-Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type,
+Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<HeapType> type,
Register object_reg,
Handle<JSObject> holder,
Handle<Name> name) {
@@ -1381,7 +856,7 @@ Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type,
}
-void LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type,
+void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
Handle<JSObject> last,
Handle<Name> name) {
Label miss;
@@ -1426,27 +901,21 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type,
Handle<Code> LoadStubCompiler::CompileLoadField(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
PropertyIndex field,
Representation representation) {
- Label miss;
-
- Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss);
-
+ Register reg = HandlerFrontend(type, receiver(), holder, name);
GenerateLoadField(reg, holder, field, representation);
- __ bind(&miss);
- TailCallBuiltin(masm(), MissBuiltin(kind()));
-
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> value) {
@@ -1459,7 +928,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(
Handle<Code> LoadStubCompiler::CompileLoadCallback(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
Handle<ExecutableAccessorInfo> callback) {
@@ -1473,22 +942,24 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<Code> LoadStubCompiler::CompileLoadCallback(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
const CallOptimization& call_optimization) {
ASSERT(call_optimization.is_simple_api_call());
Handle<JSFunction> callback = call_optimization.constant_function();
CallbackHandlerFrontend(type, receiver(), holder, name, callback);
- GenerateLoadCallback(call_optimization);
-
+ Handle<Map>receiver_map = IC::TypeToMap(*type, isolate());
+ GenerateFastApiCall(
+ masm(), call_optimization, receiver_map,
+ receiver(), scratch1(), false, 0, NULL);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
}
Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name) {
LookupResult lookup(isolate());
@@ -1541,7 +1012,7 @@ void LoadStubCompiler::GenerateLoadPostInterceptor(
Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<Code> handler,
Handle<Name> name) {
TypeHandleList types(1);
@@ -1554,12 +1025,12 @@ Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
- Handle<Type> type,
+ Handle<HeapType> type,
Handle<JSObject> holder,
Handle<Name> name,
Handle<JSFunction> getter) {
HandlerFrontend(type, receiver(), holder, name);
- GenerateLoadViaGetter(masm(), receiver(), getter);
+ GenerateLoadViaGetter(masm(), type, receiver(), getter);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
@@ -1652,10 +1123,26 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
Handle<JSObject> holder,
Handle<Name> name,
Handle<JSFunction> setter) {
+ Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
+ HandlerFrontend(type, receiver(), holder, name);
+ GenerateStoreViaSetter(masm(), type, setter);
+
+ return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ const CallOptimization& call_optimization) {
HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
receiver(), holder, name);
- GenerateStoreViaSetter(masm(), setter);
-
+ Register values[] = { value() };
+ GenerateFastApiCall(
+ masm(), call_optimization, handle(object->map()),
+ receiver(), scratch1(), true, 1, values);
+ // Return the generated code.
return GetCode(kind(), Code::FAST, name);
}
@@ -1765,8 +1252,8 @@ Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind,
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, cache_holder_);
+ ASSERT_EQ(kNoExtraICState, extra_state());
+ Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder_);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
JitEvent(name, code);
@@ -1865,83 +1352,6 @@ void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
}
-CallStubCompiler::CallStubCompiler(Isolate* isolate,
- int argc,
- Code::Kind kind,
- ExtraICState extra_state,
- InlineCacheHolderFlag cache_holder)
- : StubCompiler(isolate, extra_state),
- arguments_(argc),
- kind_(kind),
- cache_holder_(cache_holder) {
-}
-
-
-bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) {
- if (function->shared()->HasBuiltinFunctionId()) {
- BuiltinFunctionId id = function->shared()->builtin_function_id();
-#define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
- CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
-#undef CALL_GENERATOR_CASE
- }
-
- CallOptimization optimization(function);
- return optimization.is_simple_api_call();
-}
-
-
-Handle<Code> CallStubCompiler::CompileCustomCall(
- Handle<Object> object,
- Handle<JSObject> holder,
- Handle<Cell> cell,
- Handle<JSFunction> function,
- Handle<String> fname,
- Code::StubType type) {
- ASSERT(HasCustomCallGenerator(function));
-
- if (function->shared()->HasBuiltinFunctionId()) {
- BuiltinFunctionId id = function->shared()->builtin_function_id();
-#define CALL_GENERATOR_CASE(name) \
- if (id == k##name) { \
- return CallStubCompiler::Compile##name##Call(object, \
- holder, \
- cell, \
- function, \
- fname, \
- type); \
- }
- CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
-#undef CALL_GENERATOR_CASE
- }
- CallOptimization optimization(function);
- ASSERT(optimization.is_simple_api_call());
- return CompileFastApiCall(optimization,
- object,
- holder,
- cell,
- function,
- fname);
-}
-
-
-Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
- Handle<Name> name) {
- int argc = arguments_.immediate();
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind_, extra_state(), cache_holder_, type, argc);
- return GetCodeWithFlags(flags, name);
-}
-
-
-Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
- Handle<String> function_name;
- if (function->shared()->name()->IsString()) {
- function_name = Handle<String>(String::cast(function->shared()->name()));
- }
- return GetCode(Code::FAST, function_name);
-}
-
-
CallOptimization::CallOptimization(LookupResult* lookup) {
if (lookup->IsFound() &&
lookup->IsCacheable() &&
@@ -1959,20 +1369,63 @@ CallOptimization::CallOptimization(Handle<JSFunction> function) {
}
-int CallOptimization::GetPrototypeDepthOfExpectedType(
- Handle<JSObject> object,
- Handle<JSObject> holder) const {
+Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
+ Handle<Map> object_map,
+ HolderLookup* holder_lookup) const {
+ ASSERT(is_simple_api_call());
+ if (!object_map->IsJSObjectMap()) {
+ *holder_lookup = kHolderNotFound;
+ return Handle<JSObject>::null();
+ }
+ if (expected_receiver_type_.is_null() ||
+ expected_receiver_type_->IsTemplateFor(*object_map)) {
+ *holder_lookup = kHolderIsReceiver;
+ return Handle<JSObject>::null();
+ }
+ while (true) {
+ if (!object_map->prototype()->IsJSObject()) break;
+ Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
+ if (!prototype->map()->is_hidden_prototype()) break;
+ object_map = handle(prototype->map());
+ if (expected_receiver_type_->IsTemplateFor(*object_map)) {
+ *holder_lookup = kHolderFound;
+ return prototype;
+ }
+ }
+ *holder_lookup = kHolderNotFound;
+ return Handle<JSObject>::null();
+}
+
+
+bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
+ Handle<JSObject> holder) const {
ASSERT(is_simple_api_call());
- if (expected_receiver_type_.is_null()) return 0;
- int depth = 0;
- while (!object.is_identical_to(holder)) {
- if (expected_receiver_type_->IsTemplateFor(object->map())) return depth;
- object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
- if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth;
- ++depth;
+ if (!receiver->IsJSObject()) return false;
+ Handle<Map> map(JSObject::cast(*receiver)->map());
+ HolderLookup holder_lookup;
+ Handle<JSObject> api_holder =
+ LookupHolderOfExpectedType(map, &holder_lookup);
+ switch (holder_lookup) {
+ case kHolderNotFound:
+ return false;
+ case kHolderIsReceiver:
+ return true;
+ case kHolderFound:
+ if (api_holder.is_identical_to(holder)) return true;
+ // Check if holder is in prototype chain of api_holder.
+ {
+ JSObject* object = *api_holder;
+ while (true) {
+ Object* prototype = object->map()->prototype();
+ if (!prototype->IsJSObject()) return false;
+ if (prototype == *holder) return true;
+ object = JSObject::cast(prototype);
+ }
+ }
+ break;
}
- if (expected_receiver_type_->IsTemplateFor(holder->map())) return depth;
- return kInvalidProtoDepth;
+ UNREACHABLE();
+ return false;
}
« no previous file with comments | « src/stub-cache.h ('k') | src/sweeper-thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698