Commit 34697f5b authored by verwaest@chromium.org's avatar verwaest@chromium.org

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
parent 80195113
...@@ -662,7 +662,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -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);
......
...@@ -2878,7 +2878,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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);
} }
......
...@@ -133,7 +133,7 @@ enum BuiltinExtraArguments { ...@@ -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, \
......
...@@ -101,7 +101,8 @@ Handle<Code> PlatformCodeStub::GenerateCode() { ...@@ -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;
......
...@@ -251,6 +251,7 @@ class PlatformCodeStub : public CodeStub { ...@@ -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 { ...@@ -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;
}
}; };
......
...@@ -1301,7 +1301,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -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);
......
...@@ -2946,7 +2946,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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);
} }
......
...@@ -959,13 +959,23 @@ bool IC::UpdatePolymorphicIC(State state, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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));
} }
......
...@@ -4989,6 +4989,7 @@ int Code::stub_info() { ...@@ -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 ||
......
...@@ -8804,7 +8804,7 @@ void Code::FindAllCode(CodeHandleList* code_list, int length) { ...@@ -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();
......
...@@ -4280,11 +4280,6 @@ class Code: public HeapObject { ...@@ -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
}; };
......
This diff is collapsed.
...@@ -77,16 +77,15 @@ class StubCache { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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;
} }
......
...@@ -1328,7 +1328,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -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);
......
...@@ -2771,7 +2771,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment