Commit 997ad638 authored by ulan@chromium.org's avatar ulan@chromium.org

Handlify upper layers of KeyedStoreIC.

BUG=
TEST=

Review URL: http://codereview.chromium.org/8356039

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9727 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d66ea04b
...@@ -1736,9 +1736,8 @@ MaybeObject* KeyedStoreIC::Store(State state, ...@@ -1736,9 +1736,8 @@ MaybeObject* KeyedStoreIC::Store(State state,
// Check if the given name is an array index. // Check if the given name is an array index.
uint32_t index; uint32_t index;
if (name->AsArrayIndex(&index)) { if (name->AsArrayIndex(&index)) {
HandleScope scope(isolate());
Handle<Object> result = SetElement(receiver, index, value, strict_mode); Handle<Object> result = SetElement(receiver, index, value, strict_mode);
if (result.is_null()) return Failure::Exception(); RETURN_IF_EMPTY_HANDLE(isolate(), result);
return *value; return *value;
} }
...@@ -1761,17 +1760,16 @@ MaybeObject* KeyedStoreIC::Store(State state, ...@@ -1761,17 +1760,16 @@ MaybeObject* KeyedStoreIC::Store(State state,
ASSERT(!(use_ic && object->IsJSGlobalProxy())); ASSERT(!(use_ic && object->IsJSGlobalProxy()));
if (use_ic) { if (use_ic) {
Code* stub = (strict_mode == kStrictMode) Handle<Code> stub = (strict_mode == kStrictMode)
? generic_stub_strict() ? generic_stub_strict()
: generic_stub(); : generic_stub();
if (object->IsJSObject()) { if (object->IsJSObject()) {
JSObject* receiver = JSObject::cast(*object); Handle<JSObject> receiver = Handle<JSObject>::cast(object);
Heap* heap = Handle<JSObject>::cast(object)->GetHeap(); if (receiver->elements()->map() ==
Map* elements_map = Handle<JSObject>::cast(object)->elements()->map(); isolate()->heap()->non_strict_arguments_elements_map()) {
if (elements_map == heap->non_strict_arguments_elements_map()) {
stub = non_strict_arguments_stub(); stub = non_strict_arguments_stub();
} else if (!force_generic) { } else if (!force_generic) {
if (key->IsSmi() && (target() != non_strict_arguments_stub())) { if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
StubKind stub_kind = STORE_NO_TRANSITION; StubKind stub_kind = STORE_NO_TRANSITION;
if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
if (value->IsHeapNumber()) { if (value->IsHeapNumber()) {
...@@ -1784,17 +1782,11 @@ MaybeObject* KeyedStoreIC::Store(State state, ...@@ -1784,17 +1782,11 @@ MaybeObject* KeyedStoreIC::Store(State state,
stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT; stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT;
} }
} }
HandleScope scope(isolate()); stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
MaybeObject* maybe_stub = ComputeStub(receiver,
stub_kind,
strict_mode,
stub);
stub = maybe_stub->IsFailure() ?
NULL : Code::cast(maybe_stub->ToObjectUnchecked());
} }
} }
} }
if (stub != NULL) set_target(stub); if (!stub.is_null()) set_target(*stub);
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -1831,50 +1823,44 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, ...@@ -1831,50 +1823,44 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
// Compute the code stub for this store; used for rewriting to // Compute the code stub for this store; used for rewriting to
// monomorphic state and making sure that the code stub is in the // monomorphic state and making sure that the code stub is in the
// stub cache. // stub cache.
MaybeObject* maybe_code = NULL; Handle<Code> code;
Object* code = NULL;
switch (type) { switch (type) {
case FIELD: { case FIELD:
maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( code = isolate()->stub_cache()->ComputeKeyedStoreField(
*name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); name, receiver, lookup->GetFieldIndex(),
Handle<Map>::null(), strict_mode);
break; break;
} case MAP_TRANSITION:
case MAP_TRANSITION: {
if (lookup->GetAttributes() == NONE) { if (lookup->GetAttributes() == NONE) {
HandleScope scope(isolate());
ASSERT(type == MAP_TRANSITION); ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap()); Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name); int index = transition->PropertyIndexFor(*name);
maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( code = isolate()->stub_cache()->ComputeKeyedStoreField(
*name, *receiver, index, *transition, strict_mode); name, receiver, index, transition, strict_mode);
break; break;
} }
// fall through. // fall through.
} default:
default: {
// Always rewrite to the generic case so that we do not // Always rewrite to the generic case so that we do not
// repeatedly try to rewrite. // repeatedly try to rewrite.
maybe_code = (strict_mode == kStrictMode) code = (strict_mode == kStrictMode)
? generic_stub_strict() ? generic_stub_strict()
: generic_stub(); : generic_stub();
break; break;
}
} }
// If we're unable to compute the stub (not enough memory left), we ASSERT(!code.is_null());
// simply avoid updating the caches.
if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
// Patch the call site depending on the state of the cache. Make // Patch the call site depending on the state of the cache. Make
// sure to always rewrite from monomorphic to megamorphic. // sure to always rewrite from monomorphic to megamorphic.
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
if (state == UNINITIALIZED || state == PREMONOMORPHIC) { if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
set_target(Code::cast(code)); set_target(*code);
} else if (state == MONOMORPHIC) { } else if (state == MONOMORPHIC) {
set_target((strict_mode == kStrictMode) set_target((strict_mode == kStrictMode)
? megamorphic_stub_strict() ? *megamorphic_stub_strict()
: megamorphic_stub()); : *megamorphic_stub());
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -2035,7 +2021,7 @@ RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { ...@@ -2035,7 +2021,7 @@ RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) {
// Used from ic-<arch>.cc. // Used from ic-<arch>.cc.
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
NoHandleAllocation na; HandleScope scope(isolate);
ASSERT(args.length() == 3); ASSERT(args.length() == 3);
KeyedStoreIC ic(isolate); KeyedStoreIC ic(isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
...@@ -2069,7 +2055,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { ...@@ -2069,7 +2055,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
NoHandleAllocation na; HandleScope scope(isolate);
ASSERT(args.length() == 3); ASSERT(args.length() == 3);
KeyedStoreIC ic(isolate); KeyedStoreIC ic(isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
......
...@@ -603,29 +603,24 @@ class KeyedStoreIC: public KeyedIC { ...@@ -603,29 +603,24 @@ class KeyedStoreIC: public KeyedIC {
return Isolate::Current()->builtins()->builtin( return Isolate::Current()->builtins()->builtin(
Builtins::kKeyedStoreIC_Initialize); Builtins::kKeyedStoreIC_Initialize);
} }
Code* megamorphic_stub() {
return isolate()->builtins()->builtin(
Builtins::kKeyedStoreIC_Generic);
}
static Code* initialize_stub_strict() { static Code* initialize_stub_strict() {
return Isolate::Current()->builtins()->builtin( return Isolate::Current()->builtins()->builtin(
Builtins::kKeyedStoreIC_Initialize_Strict); Builtins::kKeyedStoreIC_Initialize_Strict);
} }
Code* megamorphic_stub_strict() { Handle<Code> megamorphic_stub() {
return isolate()->builtins()->builtin( return isolate()->builtins()->KeyedStoreIC_Generic();
Builtins::kKeyedStoreIC_Generic_Strict);
} }
Code* generic_stub() { Handle<Code> megamorphic_stub_strict() {
return isolate()->builtins()->builtin( return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
Builtins::kKeyedStoreIC_Generic);
} }
Code* generic_stub_strict() { Handle<Code> generic_stub() {
return isolate()->builtins()->builtin( return isolate()->builtins()->KeyedStoreIC_Generic();
Builtins::kKeyedStoreIC_Generic_Strict);
} }
Code* non_strict_arguments_stub() { Handle<Code> generic_stub_strict() {
return isolate()->builtins()->builtin( return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
Builtins::kKeyedStoreIC_NonStrictArguments); }
Handle<Code> non_strict_arguments_stub() {
return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
} }
static void Clear(Address address, Code* target); static void Clear(Address address, Code* target);
......
...@@ -687,36 +687,40 @@ Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, ...@@ -687,36 +687,40 @@ Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
return code; return code;
} }
Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
int index,
Handle<Map> transition,
Handle<String> name) {
CALL_HEAP_FUNCTION(isolate(),
CompileStoreField(*object, index,
(transition.is_null()
? NULL
: *transition),
*name),
Code);
}
MaybeObject* StubCache::ComputeKeyedStoreField(String* name, Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
JSObject* receiver, Handle<JSObject> receiver,
int field_index, int field_index,
Map* transition, Handle<Map> transition,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode) {
PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags( Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::KEYED_STORE_IC, type, strict_mode); Code::KEYED_STORE_IC, type, strict_mode);
Object* code = receiver->map()->FindInCodeCache(name, flags); Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (code->IsUndefined()) { if (probe->IsCode()) return Handle<Code>::cast(probe);
HandleScope scope(isolate());
KeyedStoreStubCompiler compiler(isolate(), strict_mode); KeyedStoreStubCompiler compiler(isolate(), strict_mode);
{ MaybeObject* maybe_code = Handle<Code> code =
compiler.CompileStoreField(receiver, field_index, transition, name); compiler.CompileStoreField(receiver, field_index, transition, name);
if (!maybe_code->ToObject(&code)) return maybe_code; PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
} GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
PROFILE(isolate(), JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
Code::cast(code), name));
GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, name, Code::cast(code)));
Object* result;
{ MaybeObject* maybe_result =
receiver->UpdateMapCodeCache(name, Code::cast(code));
if (!maybe_result->ToObject(&result)) return maybe_result;
}
}
return code; return code;
} }
#define CALL_LOGGER_TAG(kind, type) \ #define CALL_LOGGER_TAG(kind, type) \
(kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
......
...@@ -162,12 +162,11 @@ class StubCache { ...@@ -162,12 +162,11 @@ class StubCache {
// --- // ---
MUST_USE_RESULT MaybeObject* ComputeKeyedStoreField( Handle<Code> ComputeKeyedStoreField(Handle<String> name,
String* name, Handle<JSObject> receiver,
JSObject* receiver, int field_index,
int field_index, Handle<Map> transition,
Map* transition, StrictModeFlag strict_mode);
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement( MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement(
JSObject* receiver, JSObject* receiver,
...@@ -755,6 +754,11 @@ class KeyedStoreStubCompiler: public StubCompiler { ...@@ -755,6 +754,11 @@ class KeyedStoreStubCompiler: public StubCompiler {
KeyedStoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) KeyedStoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
: StubCompiler(isolate), strict_mode_(strict_mode) { } : StubCompiler(isolate), strict_mode_(strict_mode) { }
Handle<Code> CompileStoreField(Handle<JSObject> object,
int index,
Handle<Map> transition,
Handle<String> name);
MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object, MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object,
int index, int index,
Map* transition, Map* transition,
......
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