Make IC patching resilient to flushing of the original target() ic.

Review URL: https://chromiumcodereview.appspot.com/12451003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13831 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-03-05 17:38:35 +00:00
parent 80195113ab
commit 34697f5b12
15 changed files with 149 additions and 89 deletions

View File

@ -662,7 +662,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::LOAD_IC, MONOMORPHIC, Code::HANDLER_FRAGMENT); Code::STUB, MONOMORPHIC, Code::kNoExtraICState,
Code::NORMAL, Code::LOAD_IC);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, r0, r2, r3, r4, r5, r6); masm, flags, r0, r2, r3, r4, r5, r6);

View File

@ -2878,7 +2878,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ Ret(); __ Ret();
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name); return GetCode(kind(), Code::NONEXISTENT, name);
} }
@ -2974,7 +2974,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ Ret(); __ Ret();
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, name); return GetICCode(kind(), Code::NORMAL, name);
} }
@ -3002,7 +3002,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
__ Jump(ic, RelocInfo::CODE_TARGET); __ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string()); return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
} }
@ -3035,7 +3035,7 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
// Return the generated code. // Return the generated code.
InlineCacheState state = InlineCacheState state =
receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
return GetCode(Code::IC_FRAGMENT, type, name, state); return GetICCode(kind(), type, name, state);
} }

View File

@ -133,7 +133,7 @@ enum BuiltinExtraArguments {
V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC, \ V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC, \
Code::kNoExtraICState) \ Code::kNoExtraICState) \
V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \ V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \
Code::IC_FRAGMENT) \ Code::kNoExtraICState) \
V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \ V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \
Code::kNoExtraICState) \ Code::kNoExtraICState) \
V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, \ V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, \

View File

@ -101,7 +101,8 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
static_cast<Code::Kind>(GetCodeKind()), static_cast<Code::Kind>(GetCodeKind()),
GetICState(), GetICState(),
GetExtraICState(), GetExtraICState(),
GetStubType()); GetStubType(),
GetStubFlags());
Handle<Code> new_object = factory->NewCode( Handle<Code> new_object = factory->NewCode(
desc, flags, masm.CodeObject(), NeedsImmovableCode()); desc, flags, masm.CodeObject(), NeedsImmovableCode());
return new_object; return new_object;

View File

@ -251,6 +251,7 @@ class PlatformCodeStub : public CodeStub {
virtual Handle<Code> GenerateCode(); virtual Handle<Code> GenerateCode();
virtual int GetCodeKind() { return Code::STUB; } virtual int GetCodeKind() { return Code::STUB; }
virtual int GetStubFlags() { return -1; }
protected: protected:
// Generates the assembler code for the stub. // Generates the assembler code for the stub.
@ -662,11 +663,8 @@ class StoreArrayLengthStub: public StoreICStub {
class HandlerStub: public ICStub { class HandlerStub: public ICStub {
public: public:
explicit HandlerStub(Code::Kind kind) : ICStub(kind) { } explicit HandlerStub(Code::Kind kind) : ICStub(kind) { }
virtual int GetCodeKind() { return Code::STUB; }
protected: virtual int GetStubFlags() { return kind(); }
virtual Code::ExtraICState GetExtraICState() {
return Code::HANDLER_FRAGMENT;
}
}; };

View File

@ -1301,7 +1301,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::LOAD_IC, MONOMORPHIC, Code::HANDLER_FRAGMENT); Code::STUB, MONOMORPHIC, Code::kNoExtraICState,
Code::NORMAL, Code::LOAD_IC);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, edx, ecx, ebx, eax); masm, flags, edx, ecx, ebx, eax);

View File

@ -2946,7 +2946,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name); return GetCode(kind(), Code::NONEXISTENT, name);
} }
@ -3046,7 +3046,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, name); return GetICCode(kind(), Code::NORMAL, name);
} }
@ -3074,7 +3074,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string()); return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
} }
@ -3105,7 +3105,7 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
// Return the generated code. // Return the generated code.
InlineCacheState state = InlineCacheState state =
receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
return GetCode(Code::IC_FRAGMENT, type, name, state); return GetICCode(kind(), type, name, state);
} }

View File

@ -959,13 +959,23 @@ bool IC::UpdatePolymorphicIC(State state,
target()->type() == Code::NORMAL) { target()->type() == Code::NORMAL) {
return false; return false;
} }
MapHandleList receiver_maps; MapHandleList receiver_maps;
CodeHandleList handlers; CodeHandleList handlers;
target()->FindAllMaps(&receiver_maps);
int number_of_maps = receiver_maps.length();
if (number_of_maps == 0 || number_of_maps >= 4) return false;
target()->FindAllCode(&handlers, receiver_maps.length()); {
AssertNoAllocation no_gc;
target()->FindAllMaps(&receiver_maps);
int number_of_maps = receiver_maps.length();
if (number_of_maps >= 4) return false;
// Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC.
// In that case, allow the IC to go back monomorphic.
if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) {
return false;
}
target()->FindAllCode(&handlers, receiver_maps.length());
}
if (!AddOneReceiverMapIfMissing(&receiver_maps, if (!AddOneReceiverMapIfMissing(&receiver_maps,
Handle<Map>(receiver->map()))) { Handle<Map>(receiver->map()))) {
@ -1000,6 +1010,8 @@ void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
} }
// Since GC may have been invoked, by the time PatchCache is called, |state| is
// not necessarily equal to target()->state().
void IC::PatchCache(State state, void IC::PatchCache(State state,
StrictModeFlag strict_mode, StrictModeFlag strict_mode,
Handle<JSObject> receiver, Handle<JSObject> receiver,
@ -1019,11 +1031,28 @@ void IC::PatchCache(State state,
break; break;
} }
} }
// We are transitioning from monomorphic to megamorphic case. Place the if (target()->type() != Code::NORMAL) {
// stub compiled for the receiver into stub cache. // We are transitioning from monomorphic to megamorphic case. Place
Map* map = target()->FindFirstMap(); // the stub compiled for the receiver into stub cache.
if (map != NULL) { Map* map;
UpdateMegamorphicCache(map, *name, target()); Code* handler;
{
AssertNoAllocation no_gc;
map = target()->FindFirstMap();
if (map != NULL) {
if (target()->is_load_stub()) {
handler = target()->FindFirstCode();
} else {
handler = target();
}
} else {
// Avoid compiler warnings.
handler = NULL;
}
}
if (handler != NULL) {
UpdateMegamorphicCache(map, *name, handler);
}
} }
UpdateMegamorphicCache(receiver->map(), *name, *code); UpdateMegamorphicCache(receiver->map(), *name, *code);
set_target((strict_mode == kStrictMode) set_target((strict_mode == kStrictMode)
@ -1042,8 +1071,11 @@ void IC::PatchCache(State state,
} }
MapHandleList receiver_maps; MapHandleList receiver_maps;
CodeHandleList handlers; CodeHandleList handlers;
target()->FindAllMaps(&receiver_maps); {
target()->FindAllCode(&handlers, receiver_maps.length()); AssertNoAllocation no_gc;
target()->FindAllMaps(&receiver_maps);
target()->FindAllCode(&handlers, receiver_maps.length());
}
for (int i = 0; i < receiver_maps.length(); i++) { for (int i = 0; i < receiver_maps.length(); i++) {
UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
} }

View File

@ -4989,6 +4989,7 @@ int Code::stub_info() {
void Code::set_stub_info(int value) { void Code::set_stub_info(int value) {
ASSERT(kind() == COMPARE_IC || ASSERT(kind() == COMPARE_IC ||
kind() == BINARY_OP_IC || kind() == BINARY_OP_IC ||
kind() == STUB ||
kind() == LOAD_IC || kind() == LOAD_IC ||
kind() == KEYED_LOAD_IC || kind() == KEYED_LOAD_IC ||
kind() == STORE_IC || kind() == STORE_IC ||

View File

@ -8804,7 +8804,7 @@ void Code::FindAllCode(CodeHandleList* code_list, int length) {
if (i++ == length) return; if (i++ == length) return;
RelocInfo* info = it.rinfo(); RelocInfo* info = it.rinfo();
Code* code = Code::GetCodeFromTargetAddress(info->target_address()); Code* code = Code::GetCodeFromTargetAddress(info->target_address());
ASSERT(code->is_load_stub()); ASSERT(code->kind() == Code::STUB);
code_list->Add(Handle<Code>(code)); code_list->Add(Handle<Code>(code));
} }
UNREACHABLE(); UNREACHABLE();

View File

@ -4280,11 +4280,6 @@ class Code: public HeapObject {
NONEXISTENT NONEXISTENT
}; };
enum IcFragment {
IC_FRAGMENT,
HANDLER_FRAGMENT
};
enum { enum {
NUMBER_OF_KINDS = LAST_IC_KIND + 1 NUMBER_OF_KINDS = LAST_IC_KIND + 1
}; };

View File

@ -109,12 +109,12 @@ Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver,
} }
Handle<Code> StubCache::FindStub(Handle<Name> name, Handle<Code> StubCache::FindIC(Handle<Name> name,
Handle<JSObject> stub_holder, Handle<JSObject> stub_holder,
Code::Kind kind, Code::Kind kind,
Code::StubType type, Code::StubType type) {
Code::IcFragment fragment) { Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type); kind, Code::kNoExtraICState, type);
Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
isolate_); isolate_);
if (probe->IsCode()) return Handle<Code>::cast(probe); if (probe->IsCode()) return Handle<Code>::cast(probe);
@ -122,19 +122,29 @@ Handle<Code> StubCache::FindStub(Handle<Name> name,
} }
Handle<Code> StubCache::FindHandler(Handle<Name> name, Handle<Code> StubCache::FindStub(Handle<Name> name,
Handle<JSObject> handler_holder, Handle<JSObject> stub_holder,
Code::Kind kind, Code::Kind kind,
Code::StubType type) { Code::StubType type) {
return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT); ASSERT(type != Code::NORMAL);
int extra_flags = -1;
if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
extra_flags = kind;
kind = Code::STUB;
}
Code::Flags flags = Code::ComputeMonomorphicFlags(
kind, Code::kNoExtraICState, type, extra_flags);
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<JSObject> receiver, Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver,
Handle<Code> handler, Handle<Code> handler,
Handle<Name> name) { Handle<Name> name) {
Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC, Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type());
handler->type(), Code::IC_FRAGMENT);
if (!ic.is_null()) return ic; if (!ic.is_null()) return ic;
LoadStubCompiler ic_compiler(isolate()); LoadStubCompiler ic_compiler(isolate());
@ -149,8 +159,8 @@ Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver,
Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver,
Handle<Code> handler, Handle<Code> handler,
Handle<Name> name) { Handle<Name> name) {
Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC, Handle<Code> ic = FindIC(
handler->type(), Code::IC_FRAGMENT); name, receiver, Code::KEYED_LOAD_IC, handler->type());
if (!ic.is_null()) return ic; if (!ic.is_null()) return ic;
KeyedLoadStubCompiler ic_compiler(isolate()); KeyedLoadStubCompiler ic_compiler(isolate());
@ -187,7 +197,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
// Compile the stub that is either shared for all names or // Compile the stub that is either shared for all names or
// name specific if there are global objects involved. // name specific if there are global objects involved.
Handle<Code> handler = FindHandler( Handle<Code> handler = FindStub(
cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
if (!handler.is_null()) return handler; if (!handler.is_null()) return handler;
@ -211,7 +221,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
} }
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::LOAD_IC, Code::FIELD); name, stub_holder, Code::LOAD_IC, Code::FIELD);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -230,7 +240,7 @@ Handle<Code> StubCache::ComputeLoadCallback(
Handle<ExecutableAccessorInfo> callback) { Handle<ExecutableAccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0); ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -247,7 +257,7 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
Handle<JSObject> holder, Handle<JSObject> holder,
Handle<JSFunction> getter) { Handle<JSFunction> getter) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -264,7 +274,7 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
Handle<JSObject> holder, Handle<JSObject> holder,
Handle<JSFunction> value) { Handle<JSFunction> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindHandler( Handle<Code> handler = FindStub(
name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
if (!handler.is_null()) return handler; if (!handler.is_null()) return handler;
@ -280,7 +290,7 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder) { Handle<JSObject> holder) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -304,8 +314,7 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name,
Handle<JSGlobalPropertyCell> cell, Handle<JSGlobalPropertyCell> cell,
bool is_dont_delete) { bool is_dont_delete) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindStub( Handle<Code> stub = FindIC(name, stub_holder, Code::LOAD_IC, Code::NORMAL);
name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_); LoadStubCompiler compiler(isolate_);
@ -328,7 +337,7 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
} }
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -345,7 +354,7 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
Handle<JSObject> holder, Handle<JSObject> holder,
Handle<JSFunction> value) { Handle<JSFunction> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindHandler( Handle<Code> handler = FindStub(
name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
if (!handler.is_null()) return handler; if (!handler.is_null()) return handler;
@ -360,7 +369,7 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder) { Handle<JSObject> holder) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -378,7 +387,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<JSObject> holder, Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback) { Handle<ExecutableAccessorInfo> callback) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindHandler( Handle<Code> stub = FindStub(
name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
@ -895,8 +904,10 @@ Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps,
CodeHandleList* handlers, CodeHandleList* handlers,
Handle<Name> name) { Handle<Name> name) {
LoadStubCompiler ic_compiler(isolate_); LoadStubCompiler ic_compiler(isolate_);
Code::StubType type = handlers->length() == 1 ? handlers->at(0)->type()
: Code::NORMAL;
Handle<Code> ic = ic_compiler.CompilePolymorphicIC( Handle<Code> ic = ic_compiler.CompilePolymorphicIC(
receiver_maps, handlers, name, Code::NORMAL, PROPERTY); receiver_maps, handlers, name, type, PROPERTY);
return ic; return ic;
} }
@ -981,7 +992,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
Zone* zone) { Zone* zone) {
for (int i = 0; i < kPrimaryTableSize; i++) { for (int i = 0; i < kPrimaryTableSize; i++) {
if (primary_[i].key == name) { if (primary_[i].key == name) {
Map* map = primary_[i].value->FindFirstMap(); Map* map = primary_[i].map;
// Map can be NULL, if the stub is constant function call // Map can be NULL, if the stub is constant function call
// with a primitive receiver. // with a primitive receiver.
if (map == NULL) continue; if (map == NULL) continue;
@ -996,7 +1007,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
for (int i = 0; i < kSecondaryTableSize; i++) { for (int i = 0; i < kSecondaryTableSize; i++) {
if (secondary_[i].key == name) { if (secondary_[i].key == name) {
Map* map = secondary_[i].value->FindFirstMap(); Map* map = secondary_[i].map;
// Map can be NULL, if the stub is constant function call // Map can be NULL, if the stub is constant function call
// with a primitive receiver. // with a primitive receiver.
if (map == NULL) continue; if (map == NULL) continue;
@ -1005,7 +1016,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
int primary_offset = PrimaryOffset(name, flags, map); int primary_offset = PrimaryOffset(name, flags, map);
Entry* primary_entry = entry(primary_, primary_offset); Entry* primary_entry = entry(primary_, primary_offset);
if (primary_entry->key == name) { if (primary_entry->key == name) {
Map* primary_map = primary_entry->value->FindFirstMap(); Map* primary_map = primary_entry->map;
if (map == primary_map) continue; if (map == primary_map) continue;
} }
@ -1448,7 +1459,7 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
GenerateLoadMiss(masm(), kind()); GenerateLoadMiss(masm(), kind());
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name); return GetCode(kind(), Code::FIELD, name);
} }
@ -1463,7 +1474,7 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
GenerateLoadConstant(value); GenerateLoadConstant(value);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name); return GetCode(kind(), Code::CONSTANT_FUNCTION, name);
} }
@ -1480,7 +1491,7 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadCallback(
GenerateLoadCallback(reg, callback); GenerateLoadCallback(reg, callback);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); return GetCode(kind(), Code::CALLBACKS, name);
} }
@ -1500,7 +1511,7 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor(
GenerateLoadInterceptor(reg, object, holder, &lookup, name); GenerateLoadInterceptor(reg, object, holder, &lookup, name);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name); return GetCode(kind(), Code::INTERCEPTOR, name);
} }
@ -1567,7 +1578,7 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
GenerateLoadViaGetter(masm(), getter); GenerateLoadViaGetter(masm(), getter);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); return GetCode(kind(), Code::CALLBACKS, name);
} }
@ -1584,11 +1595,25 @@ void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
} }
Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment, Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind,
Code::StubType type,
Handle<Name> name,
InlineCacheState state) {
Code::Flags flags = Code::ComputeFlags(
kind, state, Code::kNoExtraICState, type);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
JitEvent(name, code);
return code;
}
Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind,
Code::StubType type, Code::StubType type,
Handle<Name> name, Handle<Name> name) {
InlineCacheState state) { ASSERT(type != Code::NORMAL);
Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type); Code::Flags flags = Code::ComputeFlags(
Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind);
Handle<Code> code = GetCodeWithFlags(flags, name); Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
JitEvent(name, code); JitEvent(name, code);

View File

@ -77,16 +77,15 @@ class StubCache {
Handle<JSObject> StubHolder(Handle<JSObject> receiver, Handle<JSObject> StubHolder(Handle<JSObject> receiver,
Handle<JSObject> holder); Handle<JSObject> holder);
Handle<Code> FindIC(Handle<Name> name,
Handle<JSObject> stub_holder,
Code::Kind kind,
Code::StubType type);
Handle<Code> FindStub(Handle<Name> name, Handle<Code> FindStub(Handle<Name> name,
Handle<JSObject> stub_holder, Handle<JSObject> stub_holder,
Code::Kind kind, Code::Kind kind,
Code::StubType type, Code::StubType type);
Code::IcFragment fragment);
Handle<Code> FindHandler(Handle<Name> name,
Handle<JSObject> stub_holder,
Code::Kind kind,
Code::StubType type);
Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver, Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver,
Handle<Code> handler, Handle<Code> handler,
@ -666,10 +665,14 @@ class BaseLoadStubCompiler: public StubCompiler {
Handle<Name> name, Handle<Name> name,
LookupResult* lookup); LookupResult* lookup);
Handle<Code> GetCode(Code::IcFragment fragment, Handle<Code> GetICCode(Code::Kind kind,
Code::StubType type,
Handle<Name> name,
InlineCacheState state = MONOMORPHIC);
Handle<Code> GetCode(Code::Kind kind,
Code::StubType type, Code::StubType type,
Handle<Name> name, Handle<Name> name);
InlineCacheState state = MONOMORPHIC);
Register receiver() { return registers_[0]; } Register receiver() { return registers_[0]; }
Register name() { return registers_[1]; } Register name() { return registers_[1]; }
@ -719,6 +722,7 @@ class LoadStubCompiler: public BaseLoadStubCompiler {
static Register* registers(); static Register* registers();
virtual Code::Kind kind() { return Code::LOAD_IC; } virtual Code::Kind kind() { return Code::LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC return code->ic_state() == MONOMORPHIC
? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG; ? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
} }
@ -746,6 +750,7 @@ class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
static Register* registers(); static Register* registers();
virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; } virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC return code->ic_state() == MONOMORPHIC
? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG; ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
} }

View File

@ -1328,7 +1328,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::LOAD_IC, MONOMORPHIC, Code::HANDLER_FRAGMENT); Code::STUB, MONOMORPHIC, Code::kNoExtraICState,
Code::NORMAL, Code::LOAD_IC);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, rax, rcx, rbx, rdx); masm, flags, rax, rcx, rbx, rdx);

View File

@ -2771,7 +2771,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name); return GetCode(kind(), Code::NONEXISTENT, name);
} }
@ -2871,7 +2871,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, name); return GetICCode(kind(), Code::NORMAL, name);
} }
@ -2898,7 +2898,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code. // Return the generated code.
return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string()); return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
} }
@ -2930,7 +2930,7 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
// Return the generated code. // Return the generated code.
InlineCacheState state = InlineCacheState state =
receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
return GetCode(Code::IC_FRAGMENT, type, name, state); return GetICCode(kind(), type, name, state);
} }