Reviewers: Toon Verwaest,
Message:
PTAL. This is needed for weak ICs.
Description:
Lazily initialize the target map list in IC.
This makes sure that we keep the target map list alive in the handle scope
during IC computation.
BUG=
[email protected]
Please review this at https://codereview.chromium.org/220923003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+46, -44 lines):
M src/ic.h
M src/ic.cc
M src/objects.h
M src/objects.cc
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
f01c3d120af1fe6bd00647712ab0e4622b4bb761..fc5707fad54743dc6145f443d872d26fb3b2dc2e
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -121,7 +121,8 @@ void IC::TraceIC(const char* type,
IC::IC(FrameDepth depth, Isolate* isolate)
: isolate_(isolate),
- target_set_(false) {
+ target_set_(false),
+ target_maps_set_(false) {
// To improve the performance of the (much used) IC code, we unfold a few
// levels of the stack frame iteration code. This yields a ~35% speedup
when
// running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic'
flag.
@@ -298,7 +299,7 @@ bool
IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
// If the IC is shared between multiple receivers (slow dictionary
mode), then
// the map cannot be deprecated and the stub invalidated.
if (cache_holder == OWN_MAP) {
- Map* old_map = target()->FindFirstMap();
+ Map* old_map = FirstTargetMap();
if (old_map == *map) return true;
if (old_map != NULL) {
if (old_map->is_deprecated()) return true;
@@ -624,7 +625,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllTypes(&types);
+ TargetTypes(&types);
int number_of_types = types.length();
int deprecated_types = 0;
int handler_to_overwrite = -1;
@@ -727,7 +728,7 @@ void IC::UpdateMonomorphicIC(Handle<HeapType> type,
void IC::CopyICToMegamorphicCache(Handle<String> name) {
TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllTypes(&types);
+ TargetTypes(&types);
if (!target()->FindHandlers(&handlers, types.length())) return;
for (int i = 0; i < types.length(); i++) {
UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
@@ -1028,19 +1029,13 @@ Handle<Code>
KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
Handle<Map> receiver_map(receiver->map(), isolate());
MapHandleList target_receiver_maps;
- if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC
state
- // yet will do so and stay there.
- return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
- }
-
if (target().is_identical_to(string_stub())) {
target_receiver_maps.Add(isolate()->factory()->string_map());
} else {
- target()->FindAllMaps(&target_receiver_maps);
- if (target_receiver_maps.length() == 0) {
- return
isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
- }
+ TargetMaps(&target_receiver_maps);
+ }
+ if (target_receiver_maps.length() == 0) {
+ return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
}
// The first time a receiver is seen that is a transitioned version of
the
@@ -1426,24 +1421,15 @@ Handle<Code>
KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
}
Handle<Map> receiver_map(receiver->map(), isolate());
- if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC
state
- // yet will do so and stay there.
+ MapHandleList target_receiver_maps;
+ TargetMaps(&target_receiver_maps);
+ if (target_receiver_maps.length() == 0) {
Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver,
store_mode);
store_mode = GetNonTransitioningStoreMode(store_mode);
return isolate()->stub_cache()->ComputeKeyedStoreElement(
monomorphic_map, strict_mode(), store_mode);
}
- MapHandleList target_receiver_maps;
- target()->FindAllMaps(&target_receiver_maps);
- if (target_receiver_maps.length() == 0) {
- // In the case that there is a non-map-specific IC is installed (e.g.
keyed
- // stores into properties in dictionary mode), then there will be not
- // receiver maps in the target.
- return generic_stub();
- }
-
// There are several special cases where an IC that is MONOMORPHIC can
still
// transition to a different GetNonTransitioningStoreMode IC that
handles a
// superset of the original IC. Handle those here if the receiver map
hasn't
@@ -2745,8 +2731,8 @@ MaybeObject* CompareNilIC::CompareNil(Handle<Object>
object) {
// Find or create the specialized stub to support the new set of types.
Handle<Code> code;
if (stub.IsMonomorphic()) {
- Handle<Map> monomorphic_map(already_monomorphic
- ? target()->FindFirstMap()
+ Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() !=
NULL
+ ? FirstTargetMap()
: HeapObject::cast(*object)->map());
code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map,
stub);
} else {
Index: src/ic.h
diff --git a/src/ic.h b/src/ic.h
index
e70cb82c96d59e132ce3994d5f099fc0c183cdad..07e9e3f0fe9204fd583560655cd1286560baef76
100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -247,6 +247,25 @@ class IC {
extra_ic_state_ = state;
}
+ void TargetMaps(MapHandleList* list) {
+ FindTargetMaps();
+ for (int i = 0; i < target_maps_.length(); i++) {
+ list->Add(target_maps_.at(i));
+ }
+ }
+
+ void TargetTypes(TypeHandleList* list) {
+ FindTargetMaps();
+ for (int i = 0; i < target_maps_.length(); i++) {
+ list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_));
+ }
+ }
+
+ Map* FirstTargetMap() {
+ FindTargetMaps();
+ return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
+ }
+
protected:
void UpdateTarget() {
target_ = handle(raw_target(), isolate_);
@@ -259,6 +278,17 @@ class IC {
inline ConstantPoolArray* constant_pool() const;
inline ConstantPoolArray* raw_constant_pool() const;
+ void FindTargetMaps() {
+ if (target_maps_set_) return;
+ target_maps_set_ = true;
+ if (state_ == MONOMORPHIC) {
+ Map* map = target_->FindFirstMap();
+ if (map != NULL) target_maps_.Add(handle(map));
+ } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
+ target_->FindAllMaps(&target_maps_);
+ }
+ }
+
// Frame pointer for the frame that uses (calls) the IC.
Address fp_;
@@ -280,6 +310,8 @@ class IC {
bool target_set_;
ExtraICState extra_ic_state_;
+ MapHandleList target_maps_;
+ bool target_maps_set_;
DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
};
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
7057e9a992f55f9f81bcb898fdb1738ca51fac95..a5d0dbf4398fe0b53b5fa14c12f18522d96bf5da
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -10540,21 +10540,6 @@ void Code::FindAllMaps(MapHandleList* maps) {
}
-void Code::FindAllTypes(TypeHandleList* types) {
- ASSERT(is_inline_cache_stub());
- DisallowHeapAllocation no_allocation;
- int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
- for (RelocIterator it(this, mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- Object* object = info->target_object();
- if (object->IsMap()) {
- Handle<Map> map(Map::cast(object));
- types->Add(IC::MapToType<HeapType>(map, map->GetIsolate()));
- }
- }
-}
-
-
Code* Code::FindFirstHandler() {
ASSERT(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
ce4dd5020b8a3f48e1ec54132f8435835679af4d..e8e20e9a3fe9bf0374bfd07a58562b73a31cb9ab
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5407,7 +5407,6 @@ class Code: public HeapObject {
// Find the first map in an IC stub.
Map* FindFirstMap();
void FindAllMaps(MapHandleList* maps);
- void FindAllTypes(TypeHandleList* types);
// Find the first handler in an IC stub.
Code* FindFirstHandler();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.