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

Unified Diff: src/ic.cc

Issue 12451003: Make IC patching resilient to flushing of the original target() ic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 10 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/ia32/stub-cache-ia32.cc ('k') | src/objects.h » ('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 7fdf6be31fbe5f36f53a22182371963d5e212be1..866fcce0c690ded60456f6c5afb3ad8660924a73 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -959,13 +959,23 @@ bool IC::UpdatePolymorphicIC(State state,
target()->type() == Code::NORMAL) {
return false;
}
+
MapHandleList receiver_maps;
CodeHandleList handlers;
- target()->FindAllMaps(&receiver_maps);
- int number_of_maps = receiver_maps.length();
- if (number_of_maps == 0 || number_of_maps >= 4) return false;
- target()->FindAllCode(&handlers, receiver_maps.length());
+ {
+ AssertNoAllocation no_gc;
+ target()->FindAllMaps(&receiver_maps);
+ int number_of_maps = receiver_maps.length();
+ 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 (map != NULL) {
- UpdateMegamorphicCache(map, *name, target());
+ 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) {
+ 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;
- target()->FindAllMaps(&receiver_maps);
- target()->FindAllCode(&handlers, receiver_maps.length());
+ {
+ 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));
}
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698