Revision: 20426
Author: [email protected]
Date: Wed Apr 2 07:59:54 2014 UTC
Log: 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]
Review URL: https://codereview.chromium.org/220923003
http://code.google.com/p/v8/source/detail?r=20426
Modified:
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
=======================================
--- /branches/bleeding_edge/src/ic.cc Tue Apr 1 14:16:54 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Wed Apr 2 07:59:54 2014 UTC
@@ -121,7 +121,8 @@
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.
@@ -293,7 +294,7 @@
// 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;
@@ -632,7 +633,7 @@
TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllTypes(&types);
+ TargetTypes(&types);
int number_of_types = types.length();
int deprecated_types = 0;
int handler_to_overwrite = -1;
@@ -735,7 +736,7 @@
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));
@@ -1036,19 +1037,13 @@
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
@@ -1435,23 +1430,14 @@
}
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
@@ -2754,8 +2740,8 @@
// 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 {
=======================================
--- /branches/bleeding_edge/src/ic.h Tue Apr 1 14:16:54 2014 UTC
+++ /branches/bleeding_edge/src/ic.h Wed Apr 2 07:59:54 2014 UTC
@@ -252,6 +252,25 @@
void set_extra_ic_state(ExtraICState state) {
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() {
@@ -265,6 +284,17 @@
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_;
@@ -286,6 +316,8 @@
bool target_set_;
ExtraICState extra_ic_state_;
+ MapHandleList target_maps_;
+ bool target_maps_set_;
DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
};
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Apr 1 11:30:31 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Wed Apr 2 07:59:54 2014 UTC
@@ -10538,21 +10538,6 @@
if (object->IsMap()) maps->Add(handle(Map::cast(object)));
}
}
-
-
-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() {
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Apr 1 11:30:31 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Wed Apr 2 07:59:54 2014 UTC
@@ -5407,7 +5407,6 @@
// 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.