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