Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Unified Diff: src/ic.cc

Issue 8233011: Refactor and fix polymorphic KeyedStoreIC creation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix nits Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index f54f0d79ed3acc7bf53e9de9988d81a285be3e76..d5056a9ce8ce3a12c5160ade1fe317383835c3b3 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1084,14 +1084,22 @@ MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
}
-MaybeObject* KeyedLoadIC::ConstructMegamorphicStub(
+MaybeObject* KeyedLoadIC::ComputePolymorphicStub(
MapList* receiver_maps,
- CodeList* targets,
StrictModeFlag strict_mode) {
+ CodeList 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(
+ 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;
KeyedLoadStubCompiler compiler;
- MaybeObject* maybe_code = compiler.CompileLoadMegamorphic(receiver_maps,
- targets);
+ MaybeObject* maybe_code = compiler.CompileLoadPolymorphic(receiver_maps,
+ &handler_ics);
if (!maybe_code->ToObject(&object)) return maybe_code;
isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
PROFILE(isolate(), CodeCreateEvent(
@@ -1625,13 +1633,16 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
} else {
GetReceiverMapsForStub(target(), &target_receiver_maps);
}
- Map* new_map = receiver->map();
+ bool map_added =
+ 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;
+ map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
}
- if (!AddOneReceiverMapIfMissing(&target_receiver_maps, new_map)) {
- // If the miss wasn't due to an unseen map, a MEGAMORPHIC stub
+ if (!map_added) {
+ // If the miss wasn't due to an unseen map, a polymorphic stub
// won't help, use the generic stub.
return generic_stub;
}
@@ -1652,13 +1663,8 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
ASSERT(maybe_cached_stub->IsCode());
return Code::cast(maybe_cached_stub);
}
- MaybeObject* maybe_stub = NULL;
- if (IsTransitionStubKind(stub_kind)) {
- maybe_stub = ComputePolymorphicStubWithTransition(
- receiver, &target_receiver_maps, new_map, strict_mode);
- } else {
- maybe_stub = ComputePolymorphicStub(&target_receiver_maps, strict_mode);
- }
+ MaybeObject* maybe_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);
@@ -1707,45 +1713,6 @@ MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver,
}
-MaybeObject* KeyedIC::ComputePolymorphicStubWithTransition(
- JSObject* receiver,
- MapList* receiver_maps,
- Map* new_map,
- StrictModeFlag strict_mode) {
- Map* existing_transitionable_map = NULL;
- for (int i = 0; i < receiver_maps->length(); ++i) {
- Map* map = receiver_maps->at(i);
- if (map != receiver->map() && map != new_map) {
- existing_transitionable_map = map;
- break;
- }
- }
- KeyedStoreStubCompiler compiler(strict_mode);
- return compiler.CompileStoreElementWithTransition(
- new_map,
- receiver->map(),
- existing_transitionable_map);
-}
-
-
-MaybeObject* KeyedIC::ComputePolymorphicStub(
- MapList* receiver_maps,
- StrictModeFlag strict_mode) {
- // Collect MONOMORPHIC stubs for all target_receiver_maps.
- CodeList 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(
- receiver_map, strict_mode);
- Code* cached_stub;
- if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
- handler_ics.Add(cached_stub);
- }
- // Build the MEGAMORPHIC stub.
- return ConstructMegamorphicStub(receiver_maps, &handler_ics, strict_mode);
-}
-
-
MaybeObject* KeyedIC::ComputeTransitionedMap(JSObject* receiver,
StubKind stub_kind) {
switch (stub_kind) {
@@ -1768,14 +1735,88 @@ MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck(
}
-MaybeObject* KeyedStoreIC::ConstructMegamorphicStub(
+// If |map| is contained in |maps_list|, returns |map|; otherwise returns NULL.
+Map* GetMapIfPresent(Map* map, MapList* maps_list) {
+ for (int i = 0; i < maps_list->length(); ++i) {
+ if (maps_list->at(i) == map) return map;
+ }
+ return NULL;
+}
+
+
+// Returns the most generic transitioned map for |map| that's found in
+// |maps_list|, or NULL if no transitioned map for |map| is found at all.
+Map* GetTransitionedMap(Map* map, MapList* maps_list) {
+ ElementsKind elements_kind = map->elements_kind();
+ if (elements_kind == FAST_ELEMENTS) {
+ return NULL;
+ }
+ if (elements_kind == FAST_DOUBLE_ELEMENTS) {
+ bool dummy = true;
+ Map* fast_map = map->LookupElementsTransitionMap(FAST_ELEMENTS, &dummy);
+ if (fast_map == NULL) return NULL;
+ return GetMapIfPresent(fast_map, maps_list);
+ }
+ if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
+ bool dummy = true;
+ Map* double_map = map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS,
+ &dummy);
+ // In the current implementation, if the DOUBLE map doesn't exist, the
+ // FAST map can't exist either.
+ if (double_map == NULL) return NULL;
+ Map* fast_map = map->LookupElementsTransitionMap(FAST_ELEMENTS, &dummy);
+ if (fast_map == NULL) {
+ return GetMapIfPresent(double_map, maps_list);
+ }
+ // Both double_map and fast_map are non-NULL. Return fast_map if it's in
+ // maps_list, double_map otherwise.
+ Map* fast_map_present = GetMapIfPresent(fast_map, maps_list);
+ if (fast_map_present != NULL) return fast_map_present;
+ return GetMapIfPresent(double_map, maps_list);
+ }
+ return NULL;
+}
+
+
+MaybeObject* KeyedStoreIC::ComputePolymorphicStub(
MapList* receiver_maps,
- CodeList* targets,
StrictModeFlag strict_mode) {
+ // TODO(yangguo): <remove>
+ Code* generic_stub = (strict_mode == kStrictMode)
+ ? isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic_Strict)
+ : isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic);
+ // </remove>
+
+ // Collect MONOMORPHIC stubs for all target_receiver_maps.
+ CodeList handler_ics(receiver_maps->length());
+ MapList 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 = GetTransitionedMap(receiver_map, receiver_maps);
+ if (transitioned_map != NULL) {
+ // TODO(yangguo): Enable this code!
+ // maybe_cached_stub = FastElementsConversionStub(
+ // receiver_map->elements_kind(), // original elements_kind
+ // transitioned_map->elements_kind(),
+ // receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array
+ // strict_mode_).TryGetCode();
+ // TODO(yangguo): <remove>
+ maybe_cached_stub = generic_stub;
+ // </remove>
+ } else {
+ maybe_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);
+ transitioned_maps.Add(transitioned_map);
+ }
Object* object;
KeyedStoreStubCompiler compiler(strict_mode);
- MaybeObject* maybe_code = compiler.CompileStoreMegamorphic(receiver_maps,
- targets);
+ MaybeObject* maybe_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(
« no previous file with comments | « src/ic.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698