Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index b4a333ec90781a551548562ba5ccb9bb06b9ee94..5b62a8a09c80321721c91b002c257348cc8af88e 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -299,6 +299,7 @@ void LoadIC::ClearInlinedVersion(Address address) { |
// present) to guarantee failure by holding an invalid map (the null |
// value). The offset can be patched to anything. |
PatchInlinedLoad(address, Heap::null_value(), 0); |
+ PatchInlinedContextualLoad(address, Heap::null_value(), Heap::null_value()); |
} |
@@ -720,6 +721,14 @@ Object* KeyedCallIC::LoadFunction(State state, |
} |
+#ifdef DEBUG |
+#define TRACE_IC_NAMED(msg, name) \ |
+ if (FLAG_trace_ic) PrintF(msg, *(name)->ToCString()) |
+#else |
+#define TRACE_IC_NAMED(msg, name) |
+#endif |
+ |
+ |
Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) { |
// If the object is undefined or null it's illegal to try to get any |
// of its properties; throw a TypeError in that case. |
@@ -797,15 +806,24 @@ Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) { |
LOG(SuspectReadEvent(*name, *object)); |
} |
- bool can_be_inlined = |
+ bool can_be_inlined_precheck = |
FLAG_use_ic && |
- state == PREMONOMORPHIC && |
lookup.IsProperty() && |
lookup.IsCacheable() && |
lookup.holder() == *object && |
- lookup.type() == FIELD && |
!object->IsAccessCheckNeeded(); |
+ bool can_be_inlined = |
+ can_be_inlined_precheck && |
+ state == PREMONOMORPHIC && |
+ lookup.type() == FIELD; |
+ |
+ bool can_be_inlined_contextual = |
+ can_be_inlined_precheck && |
+ state == UNINITIALIZED && |
+ lookup.holder()->IsGlobalObject() && |
+ lookup.type() == NORMAL; |
+ |
if (can_be_inlined) { |
Map* map = lookup.holder()->map(); |
// Property's index in the properties array. If negative we have |
@@ -816,32 +834,29 @@ Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) { |
int offset = map->instance_size() + (index * kPointerSize); |
if (PatchInlinedLoad(address(), map, offset)) { |
set_target(megamorphic_stub()); |
-#ifdef DEBUG |
- if (FLAG_trace_ic) { |
- PrintF("[LoadIC : inline patch %s]\n", *name->ToCString()); |
- } |
-#endif |
+ TRACE_IC_NAMED("[LoadIC : inline patch %s]\n", name); |
return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); |
-#ifdef DEBUG |
} else { |
- if (FLAG_trace_ic) { |
- PrintF("[LoadIC : no inline patch %s (patching failed)]\n", |
- *name->ToCString()); |
- } |
+ TRACE_IC_NAMED("[LoadIC : no inline patch %s (patching failed)]\n", |
+ name); |
} |
} else { |
- if (FLAG_trace_ic) { |
- PrintF("[LoadIC : no inline patch %s (not inobject)]\n", |
- *name->ToCString()); |
- } |
+ TRACE_IC_NAMED("[LoadIC : no inline patch %s (not inobject)]\n", name); |
+ } |
+ } else if (can_be_inlined_contextual) { |
+ Map* map = lookup.holder()->map(); |
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( |
+ lookup.holder()->property_dictionary()->ValueAt( |
+ lookup.GetDictionaryEntry())); |
+ if (PatchInlinedContextualLoad(address(), map, cell)) { |
+ set_target(megamorphic_stub()); |
+ TRACE_IC_NAMED("[LoadIC : inline contextual patch %s]\n", name); |
+ ASSERT(cell->value() != Heap::the_hole_value()); |
+ return cell->value(); |
} |
} else { |
if (FLAG_use_ic && state == PREMONOMORPHIC) { |
- if (FLAG_trace_ic) { |
- PrintF("[LoadIC : no inline patch %s (not inlinable)]\n", |
- *name->ToCString()); |
-#endif |
- } |
+ TRACE_IC_NAMED("[LoadIC : no inline patch %s (not inlinable)]\n", name); |
} |
} |