}
-MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
+Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck(
bool is_js_array,
ElementsKind elements_kind) {
- return KeyedLoadElementStub(elements_kind).TryGetCode();
+ return KeyedLoadElementStub(elements_kind).GetCode();
}
-MaybeObject* KeyedLoadIC::ComputePolymorphicStub(
- MapList* receiver_maps,
+Handle<Code> KeyedLoadIC::ComputePolymorphicStub(
+ MapHandleList* receiver_maps,
StrictModeFlag strict_mode) {
- CodeList handler_ics(receiver_maps->length());
+ CodeHandleList handler_ics(receiver_maps->length());
for (int i = 0; i < receiver_maps->length(); ++i) {
- Map* receiver_map(receiver_maps->at(i));
- MaybeObject* maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
+ Handle<Map> receiver_map = receiver_maps->at(i);
+ Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck(
receiver_map, strict_mode);
- Code* cached_stub;
- if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
handler_ics.Add(cached_stub);
}
- Object* object;
- HandleScope scope(isolate());
KeyedLoadStubCompiler compiler(isolate());
- MaybeObject* maybe_code = compiler.CompileLoadPolymorphic(receiver_maps,
- &handler_ics);
- if (!maybe_code->ToObject(&object)) return maybe_code;
+ Handle<Code> code = compiler.CompileLoadPolymorphic(
+ receiver_maps, &handler_ics);
isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
- PROFILE(isolate(), CodeCreateEvent(
- Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG,
- Code::cast(object), 0));
- return object;
+ PROFILE(isolate(),
+ CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0));
+ return code;
}
name->Equals(isolate()->heap()->length_symbol())) {
Handle<String> string = Handle<String>::cast(object);
Handle<Code> code =
- isolate()->stub_cache()->ComputeKeyedLoadStringLength(name,
- string);
+ isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string);
ASSERT(!code.is_null());
set_target(*code);
TRACE_IC("KeyedLoadIC", name, state, target());
}
-static bool AddOneReceiverMapIfMissing(MapList* receiver_maps,
- Map* new_receiver_map) {
+static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
+ Handle<Map> new_receiver_map) {
+ ASSERT(!new_receiver_map.is_null());
for (int current = 0; current < receiver_maps->length(); ++current) {
- if (receiver_maps->at(current) == new_receiver_map) {
+ if (!receiver_maps->at(current).is_null() &&
+ receiver_maps->at(current).is_identical_to(new_receiver_map)) {
return false;
}
}
}
-void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) {
+void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
+ MapHandleList* result) {
ASSERT(stub->is_inline_cache_stub());
- if (!string_stub().is_null() && stub == *string_stub()) {
- return result->Add(isolate()->heap()->string_map());
+ if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
+ return result->Add(isolate()->factory()->string_map());
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
if (stub->ic_state() == MONOMORPHIC) {
- result->Add(Map::cast(stub->FindFirstMap()));
+ result->Add(Handle<Map>(stub->FindFirstMap()));
} else {
ASSERT(stub->ic_state() == MEGAMORPHIC);
AssertNoAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
- for (RelocIterator it(stub, mask); !it.done(); it.next()) {
+ for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
- Object* object = info->target_object();
+ Handle<Object> object(info->target_object());
ASSERT(object->IsMap());
- AddOneReceiverMapIfMissing(result, Map::cast(object));
+ AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
}
}
}
StubKind stub_kind,
StrictModeFlag strict_mode,
Handle<Code> generic_stub) {
- CALL_HEAP_FUNCTION(isolate(),
- ComputeStub(*receiver,
- stub_kind,
- strict_mode,
- *generic_stub),
- Code);
-}
-
-
-
-MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
- StubKind stub_kind,
- StrictModeFlag strict_mode,
- Code* generic_stub) {
State ic_state = target()->ic_state();
if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) &&
!IsTransitionStubKind(stub_kind)) {
- Code* monomorphic_stub;
- MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver,
- stub_kind,
- strict_mode,
- generic_stub);
- if (!maybe_stub->To(&monomorphic_stub)) return maybe_stub;
-
- return monomorphic_stub;
+ return ComputeMonomorphicStub(
+ receiver, stub_kind, strict_mode, generic_stub);
}
- ASSERT(target() != generic_stub);
+ ASSERT(target() != *generic_stub);
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
// via megamorphic stubs, since they don't have a map in their relocation info
// Determine the list of receiver maps that this call site has seen,
// adding the map that was just encountered.
- MapList target_receiver_maps;
+ MapHandleList target_receiver_maps;
+ Handle<Map> receiver_map(receiver->map());
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
- target_receiver_maps.Add(receiver->map());
+ target_receiver_maps.Add(receiver_map);
} else {
- GetReceiverMapsForStub(target(), &target_receiver_maps);
+ GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
}
bool map_added =
- AddOneReceiverMapIfMissing(&target_receiver_maps, receiver->map());
+ AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
if (IsTransitionStubKind(stub_kind)) {
- MaybeObject* maybe_map = ComputeTransitionedMap(receiver, stub_kind);
- Map* new_map = NULL;
- if (!maybe_map->To(&new_map)) return maybe_map;
+ Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
}
if (!map_added) {
return generic_stub;
}
- PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
- Code::Flags flags = Code::ComputeFlags(this->kind(),
- MEGAMORPHIC,
- strict_mode);
- Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
- // If there is a cached stub, use it.
- if (!maybe_cached_stub->IsUndefined()) {
- ASSERT(maybe_cached_stub->IsCode());
- return Code::cast(maybe_cached_stub);
- }
- MaybeObject* maybe_stub =
+ Handle<PolymorphicCodeCache> cache =
+ isolate()->factory()->polymorphic_code_cache();
+ Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode);
+ Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ Handle<Code> stub =
ComputePolymorphicStub(&target_receiver_maps, strict_mode);
- Code* stub;
- if (!maybe_stub->To(&stub)) return maybe_stub;
- MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub);
- if (maybe_update->IsFailure()) return maybe_update;
+ PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub);
return stub;
}
-MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
- Map* receiver_map,
+Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
+ Handle<Map> receiver_map,
StrictModeFlag strict_mode) {
if ((receiver_map->instance_type() & kNotStringTag) == 0) {
ASSERT(!string_stub().is_null());
- return *string_stub();
+ return string_stub();
} else {
ASSERT(receiver_map->has_dictionary_elements() ||
receiver_map->has_fast_elements() ||
}
-MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver,
+Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver,
StubKind stub_kind,
StrictModeFlag strict_mode,
- Code* generic_stub) {
- Code* result = NULL;
+ Handle<Code> generic_stub) {
if (receiver->HasFastElements() ||
receiver->HasFastSmiOnlyElements() ||
receiver->HasExternalArrayElements() ||
receiver->HasFastDoubleElements() ||
receiver->HasDictionaryElements()) {
- MaybeObject* maybe_stub =
- isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
- receiver, stub_kind, strict_mode);
- if (!maybe_stub->To(&result)) return maybe_stub;
+ return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
+ receiver, stub_kind, strict_mode);
} else {
- result = generic_stub;
+ return generic_stub;
}
- return result;
}
-MaybeObject* KeyedIC::ComputeTransitionedMap(JSObject* receiver,
- StubKind stub_kind) {
+Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
+ StubKind stub_kind) {
switch (stub_kind) {
case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT:
case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT:
- return receiver->GetElementsTransitionMap(FAST_ELEMENTS);
+ return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
+ break;
case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE:
- return receiver->GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
+ return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
+ break;
default:
UNREACHABLE();
- return NULL;
+ return Handle<Map>::null();
}
}
-MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck(
+Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck(
bool is_js_array,
ElementsKind elements_kind) {
- return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
+ return KeyedStoreElementStub(is_js_array, elements_kind).GetCode();
}
-MaybeObject* KeyedStoreIC::ComputePolymorphicStub(
- MapList* receiver_maps,
- StrictModeFlag strict_mode) {
+Handle<Code> KeyedStoreIC::ComputePolymorphicStub(MapHandleList* receiver_maps,
+ StrictModeFlag strict_mode) {
// Collect MONOMORPHIC stubs for all target_receiver_maps.
- CodeList handler_ics(receiver_maps->length());
- MapList transitioned_maps(receiver_maps->length());
+ CodeHandleList handler_ics(receiver_maps->length());
+ MapHandleList transitioned_maps(receiver_maps->length());
for (int i = 0; i < receiver_maps->length(); ++i) {
- Map* receiver_map(receiver_maps->at(i));
- MaybeObject* maybe_cached_stub = NULL;
- Map* transitioned_map = receiver_map->FindTransitionedMap(receiver_maps);
- if (transitioned_map != NULL) {
- maybe_cached_stub = ElementsTransitionAndStoreStub(
+ Handle<Map> receiver_map(receiver_maps->at(i));
+ Handle<Code> cached_stub;
+ Handle<Map> transitioned_map =
+ receiver_map->FindTransitionedMap(receiver_maps);
+ if (!transitioned_map.is_null()) {
+ cached_stub = ElementsTransitionAndStoreStub(
receiver_map->elements_kind(), // original elements_kind
transitioned_map->elements_kind(),
receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array
- strict_mode).TryGetCode();
+ strict_mode).GetCode();
} else {
- maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
- receiver_map, strict_mode);
+ cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map,
+ strict_mode);
}
- Code* cached_stub;
- if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
+ ASSERT(!cached_stub.is_null());
handler_ics.Add(cached_stub);
transitioned_maps.Add(transitioned_map);
}
- Object* object;
- HandleScope scope(isolate());
KeyedStoreStubCompiler compiler(isolate(), strict_mode);
- MaybeObject* maybe_code = compiler.CompileStorePolymorphic(
+ Handle<Code> code = compiler.CompileStorePolymorphic(
receiver_maps, &handler_ics, &transitioned_maps);
- if (!maybe_code->ToObject(&object)) return maybe_code;
isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
- PROFILE(isolate(), CodeCreateEvent(
- Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG,
- Code::cast(object), 0));
- return object;
+ PROFILE(isolate(),
+ CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
+ return code;
}
explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
virtual ~KeyedIC() {}
- virtual MaybeObject* GetElementStubWithoutMapCheck(
+ virtual Handle<Code> GetElementStubWithoutMapCheck(
bool is_js_array,
ElementsKind elements_kind) = 0;
StrictModeFlag strict_mode,
Handle<Code> default_stub);
- MaybeObject* ComputeStub(JSObject* receiver,
- StubKind stub_kind,
- StrictModeFlag strict_mode,
- Code* default_stub);
-
- virtual MaybeObject* ComputePolymorphicStub(MapList* receiver_maps,
+ virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
StrictModeFlag strict_mode) = 0;
- MaybeObject* ComputeMonomorphicStubWithoutMapCheck(
- Map* receiver_map,
+ Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
+ Handle<Map> receiver_map,
StrictModeFlag strict_mode);
private:
- void GetReceiverMapsForStub(Code* stub, MapList* result);
+ void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
- MaybeObject* ComputeMonomorphicStub(JSObject* receiver,
+ Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver,
StubKind stub_kind,
StrictModeFlag strict_mode,
- Code* default_stub);
+ Handle<Code> default_stub);
- MaybeObject* ComputeTransitionedMap(JSObject* receiver, StubKind stub_kind);
+ Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
+ StubKind stub_kind);
static bool IsTransitionStubKind(StubKind stub_kind) {
return stub_kind > STORE_NO_TRANSITION;
static const int kSlowCaseBitFieldMask =
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
- virtual MaybeObject* GetElementStubWithoutMapCheck(
+ virtual Handle<Code> GetElementStubWithoutMapCheck(
bool is_js_array,
ElementsKind elements_kind);
protected:
virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
- virtual MaybeObject* ComputePolymorphicStub(
- MapList* receiver_maps,
- StrictModeFlag strict_mode);
+ virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
+ StrictModeFlag strict_mode);
virtual Handle<Code> string_stub() {
return isolate()->builtins()->KeyedLoadIC_String();
static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);
- virtual MaybeObject* GetElementStubWithoutMapCheck(
+ virtual Handle<Code> GetElementStubWithoutMapCheck(
bool is_js_array,
ElementsKind elements_kind);
protected:
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
- virtual MaybeObject* ComputePolymorphicStub(
- MapList* receiver_maps,
- StrictModeFlag strict_mode);
+ virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
+ StrictModeFlag strict_mode);
private:
// Update the inline cache.
}
-MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement(
- JSObject* receiver,
+Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(Handle<Map> map) {
+ CALL_HEAP_FUNCTION(isolate(),
+ (set_failure(NULL), CompileLoadElement(*map)),
+ Code);
+}
+
+
+Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(Handle<Map> map) {
+ CALL_HEAP_FUNCTION(isolate(),
+ (set_failure(NULL),
+ CompileStoreElement(*map)),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadOrStoreElement(
+ Handle<JSObject> receiver,
KeyedIC::StubKind stub_kind,
StrictModeFlag strict_mode) {
Code::Flags flags =
: Code::KEYED_STORE_IC,
NORMAL,
strict_mode);
- String* name = NULL;
+ Handle<String> name;
switch (stub_kind) {
case KeyedIC::LOAD:
- name = isolate()->heap()->KeyedLoadElementMonomorphic_symbol();
+ name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
break;
case KeyedIC::STORE_NO_TRANSITION:
- name = isolate()->heap()->KeyedStoreElementMonomorphic_symbol();
+ name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol();
break;
default:
UNREACHABLE();
break;
}
- Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
- if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
+ Handle<Map> receiver_map(receiver->map());
+ Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
- Map* receiver_map = receiver->map();
- MaybeObject* maybe_new_code = NULL;
+ Handle<Code> code;
switch (stub_kind) {
case KeyedIC::LOAD: {
- HandleScope scope(isolate_);
KeyedLoadStubCompiler compiler(isolate_);
- maybe_new_code = compiler.CompileLoadElement(receiver_map);
+ code = compiler.CompileLoadElement(receiver_map);
break;
}
case KeyedIC::STORE_NO_TRANSITION: {
- HandleScope scope(isolate_);
KeyedStoreStubCompiler compiler(isolate_, strict_mode);
- maybe_new_code = compiler.CompileStoreElement(receiver_map);
+ code = compiler.CompileStoreElement(receiver_map);
break;
}
default:
UNREACHABLE();
break;
}
- Code* code = NULL;
- if (!maybe_new_code->To(&code)) return maybe_new_code;
+
+ ASSERT(!code.is_null());
if (stub_kind == KeyedIC::LOAD) {
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
- Code::cast(code), 0));
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
} else {
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
- Code::cast(code), 0));
- }
- ASSERT(code->IsCode());
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
}
+ JSObject::UpdateMapCodeCache(receiver, name, code);
return code;
}
+Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
+ MapHandleList* receiver_maps,
+ CodeHandleList* handler_stubs) {
+ MapList raw_receiver_maps(receiver_maps->length());
+ CodeList raw_handler_stubs(handler_stubs->length());
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ (set_failure(NULL),
+ raw_receiver_maps.Clear(),
+ raw_handler_stubs.Clear(),
+ CompileLoadPolymorphic(UnwrapHandleList(&raw_receiver_maps,
+ receiver_maps),
+ UnwrapHandleList(&raw_handler_stubs,
+ handler_stubs))),
+ Code);
+}
+
+
+Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
+ MapHandleList* receiver_maps,
+ CodeHandleList* handler_stubs,
+ MapHandleList* transitioned_maps) {
+ MapList raw_receiver_maps(receiver_maps->length());
+ CodeList raw_handler_stubs(handler_stubs->length());
+ MapList raw_transitioned_maps(transitioned_maps->length());
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ (set_failure(NULL),
+ raw_receiver_maps.Clear(),
+ raw_handler_stubs.Clear(),
+ raw_transitioned_maps.Clear(),
+ CompileStorePolymorphic(UnwrapHandleList(&raw_receiver_maps,
+ receiver_maps),
+ UnwrapHandleList(&raw_handler_stubs,
+ handler_stubs),
+ UnwrapHandleList(&raw_transitioned_maps,
+ transitioned_maps))),
+ Code);
+}
+
+
Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
return (strict_mode == kStrictMode)
? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()