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) {
// Probe the stub cache.
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(
masm, flags, r0, r2, r3, r4, r5, r6);
......
......@@ -2878,7 +2878,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ Ret();
// 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();
// 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);
// 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.
InlineCacheState state =
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 {
V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC, \
Code::kNoExtraICState) \
V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \
Code::IC_FRAGMENT) \
Code::kNoExtraICState) \
V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \
Code::kNoExtraICState) \
V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, \
......
......@@ -101,7 +101,8 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
static_cast<Code::Kind>(GetCodeKind()),
GetICState(),
GetExtraICState(),
GetStubType());
GetStubType(),
GetStubFlags());
Handle<Code> new_object = factory->NewCode(
desc, flags, masm.CodeObject(), NeedsImmovableCode());
return new_object;
......
......@@ -251,6 +251,7 @@ class PlatformCodeStub : public CodeStub {
virtual Handle<Code> GenerateCode();
virtual int GetCodeKind() { return Code::STUB; }
virtual int GetStubFlags() { return -1; }
protected:
// Generates the assembler code for the stub.
......@@ -662,11 +663,8 @@ class StoreArrayLengthStub: public StoreICStub {
class HandlerStub: public ICStub {
public:
explicit HandlerStub(Code::Kind kind) : ICStub(kind) { }
protected:
virtual Code::ExtraICState GetExtraICState() {
return Code::HANDLER_FRAGMENT;
}
virtual int GetCodeKind() { return Code::STUB; }
virtual int GetStubFlags() { return kind(); }
};
......
......@@ -1301,7 +1301,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// Probe the stub cache.
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(
masm, flags, edx, ecx, ebx, eax);
......
......@@ -2946,7 +2946,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ ret(0);
// 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);
// 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);
// 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.
InlineCacheState state =
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,
target()->type() == Code::NORMAL) {
return false;
}
MapHandleList receiver_maps;
CodeHandleList handlers;
{
AssertNoAllocation no_gc;
target()->FindAllMaps(&receiver_maps);
int number_of_maps = receiver_maps.length();
if (number_of_maps == 0 || number_of_maps >= 4) return false;
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,
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,
StrictModeFlag strict_mode,
Handle<JSObject> receiver,
......@@ -1019,11 +1031,28 @@ void IC::PatchCache(State state,
break;
}
}
// We are transitioning from monomorphic to megamorphic case. Place the
// stub compiled for the receiver into stub cache.
Map* map = target()->FindFirstMap();
if (target()->type() != Code::NORMAL) {
// We are transitioning from monomorphic to megamorphic case. Place
// the stub compiled for the receiver into stub cache.
Map* map;
Code* handler;
{
AssertNoAllocation no_gc;
map = target()->FindFirstMap();
if (map != NULL) {
UpdateMegamorphicCache(map, *name, target());
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);
set_target((strict_mode == kStrictMode)
......@@ -1042,8 +1071,11 @@ void IC::PatchCache(State state,
}
MapHandleList receiver_maps;
CodeHandleList handlers;
{
AssertNoAllocation no_gc;
target()->FindAllMaps(&receiver_maps);
target()->FindAllCode(&handlers, receiver_maps.length());
}
for (int i = 0; i < receiver_maps.length(); i++) {
UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
}
......
......@@ -4989,6 +4989,7 @@ int Code::stub_info() {
void Code::set_stub_info(int value) {
ASSERT(kind() == COMPARE_IC ||
kind() == BINARY_OP_IC ||
kind() == STUB ||
kind() == LOAD_IC ||
kind() == KEYED_LOAD_IC ||
kind() == STORE_IC ||
......
......@@ -8804,7 +8804,7 @@ void Code::FindAllCode(CodeHandleList* code_list, int length) {
if (i++ == length) return;
RelocInfo* info = it.rinfo();
Code* code = Code::GetCodeFromTargetAddress(info->target_address());
ASSERT(code->is_load_stub());
ASSERT(code->kind() == Code::STUB);
code_list->Add(Handle<Code>(code));
}
UNREACHABLE();
......
......@@ -4280,11 +4280,6 @@ class Code: public HeapObject {
NONEXISTENT
};
enum IcFragment {
IC_FRAGMENT,
HANDLER_FRAGMENT
};
enum {
NUMBER_OF_KINDS = LAST_IC_KIND + 1
};
......
This diff is collapsed.
......@@ -77,13 +77,12 @@ class StubCache {
Handle<JSObject> StubHolder(Handle<JSObject> receiver,
Handle<JSObject> holder);
Handle<Code> FindStub(Handle<Name> name,
Handle<Code> FindIC(Handle<Name> name,
Handle<JSObject> stub_holder,
Code::Kind kind,
Code::StubType type,
Code::IcFragment fragment);
Code::StubType type);
Handle<Code> FindHandler(Handle<Name> name,
Handle<Code> FindStub(Handle<Name> name,
Handle<JSObject> stub_holder,
Code::Kind kind,
Code::StubType type);
......@@ -666,11 +665,15 @@ class BaseLoadStubCompiler: public StubCompiler {
Handle<Name> name,
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,
Handle<Name> name);
Register receiver() { return registers_[0]; }
Register name() { return registers_[1]; }
Register scratch1() { return registers_[2]; }
......@@ -719,6 +722,7 @@ class LoadStubCompiler: public BaseLoadStubCompiler {
static Register* registers();
virtual Code::Kind kind() { return Code::LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
}
......@@ -746,6 +750,7 @@ class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
static Register* registers();
virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
}
......
......@@ -1328,7 +1328,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// Probe the stub cache.
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(
masm, flags, rax, rcx, rbx, rdx);
......
......@@ -2771,7 +2771,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
__ ret(0);
// 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);
// 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);
// 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.
InlineCacheState state =
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