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

Unified Diff: src/ic.cc

Issue 14146005: Track representations of fields (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for tracking fields Created 7 years, 8 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/json-parser.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 e0ebdddf018c0046d83d15f8ab1c0916a84e47ad..56877a5eae5ab836cb4b57a1a4e3f45d74f9fea1 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -182,6 +182,15 @@ Address IC::OriginalCodeAddress() const {
static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
Object* receiver,
Object* name) {
+ // If the code is NORMAL, it handles dictionary mode objects. Such stubs do
+ // not check maps, but do positive/negative lookups.
+ if (target->type() != Code::NORMAL) {
+ Map* map = target->FindFirstMap();
+ if (map != NULL && map->is_deprecated()) {
+ return true;
+ }
+ }
+
InlineCacheHolderFlag cache_holder =
Code::ExtractCacheHolderFromFlags(target->flags());
@@ -505,6 +514,13 @@ MaybeObject* CallICBase::LoadFunction(State state,
Code::ExtraICState extra_ic_state,
Handle<Object> object,
Handle<String> name) {
+ if (object->IsJSObject()) {
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
+ }
+
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
@@ -776,6 +792,13 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
Handle<String>::cast(key));
}
+ if (object->IsJSObject()) {
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
+ }
+
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_call", object, key);
}
@@ -890,6 +913,13 @@ MaybeObject* LoadIC::Load(State state,
return Runtime::GetElementOrCharAtOrFail(isolate(), object, index);
}
+ if (object->IsJSObject()) {
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
+ }
+
// Named lookup in the object.
LookupResult lookup(isolate());
LookupForRead(object, name, &lookup);
@@ -954,11 +984,19 @@ bool IC::UpdatePolymorphicIC(State state,
MapHandleList receiver_maps;
CodeHandleList handlers;
+ int number_of_valid_maps;
{
AssertNoAllocation no_gc;
target()->FindAllMaps(&receiver_maps);
int number_of_maps = receiver_maps.length();
- if (number_of_maps >= 4) return false;
+ number_of_valid_maps = number_of_maps;
+ for (int i = 0; i < number_of_maps; i++) {
+ if (receiver_maps.at(i)->is_deprecated()) {
+ number_of_valid_maps--;
+ }
+ }
+
+ if (number_of_valid_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.
@@ -975,7 +1013,7 @@ bool IC::UpdatePolymorphicIC(State state,
handlers.Add(code);
Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
- &receiver_maps, &handlers, name);
+ &receiver_maps, &handlers, number_of_valid_maps + 1, name);
set_target(*ic);
return true;
}
@@ -1066,6 +1104,28 @@ void IC::PatchCache(State state,
if (target()->type() != Code::NORMAL) {
if (target()->is_load_stub()) {
CopyICToMegamorphicCache(name);
+ } else if (target()->is_store_stub()) {
+ // Ensure that the IC stays monomorphic when replacing a monomorphic
+ // IC for a deprecated map.
+ // TODO(verwaest): Remove this code once polymorphic store ICs are
+ // implemented. Updating the polymorphic IC will keep it monomorphic
+ // by filtering deprecated maps.
+ MapHandleList maps;
+ Code* handler = target();
+ handler->FindAllMaps(&maps);
+ for (int i = 0; i < Min(1, maps.length()); i++) {
+ if (maps.at(i)->is_deprecated()) {
+ UpdateMonomorphicIC(receiver, code, name);
+ return;
+ }
+ }
+ if (maps.length() > 0) {
+ if (receiver->map() == *maps.at(0)) {
+ UpdateMonomorphicIC(receiver, code, name);
+ return;
+ }
+ UpdateMegamorphicCache(*maps.at(0), *name, handler);
+ }
} else {
Code* handler = target();
Map* map = handler->FindFirstMap();
@@ -1365,6 +1425,10 @@ MaybeObject* KeyedLoadIC::Load(State state,
}
} else if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
+
if (receiver->elements()->map() ==
isolate()->heap()->non_strict_arguments_elements_map()) {
stub = non_strict_arguments_stub();
@@ -1431,6 +1495,7 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
static bool LookupForWrite(Handle<JSObject> receiver,
Handle<String> name,
+ Handle<Object> value,
LookupResult* lookup) {
Handle<JSObject> holder = receiver;
receiver->Lookup(*name, lookup);
@@ -1443,9 +1508,10 @@ static bool LookupForWrite(Handle<JSObject> receiver,
receiver->LocalLookupRealNamedProperty(*name, lookup);
return lookup->IsFound() &&
!lookup->IsReadOnly() &&
+ lookup->CanHoldValue(value) &&
lookup->IsCacheable();
}
- return true;
+ return lookup->CanHoldValue(value);
}
if (lookup->IsPropertyCallbacks()) return true;
@@ -1463,8 +1529,11 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// chain check. This avoids a double lookup, but requires us to pass in the
// receiver when trying to fetch extra information from the transition.
receiver->map()->LookupTransition(*holder, *name, lookup);
- return lookup->IsTransition() &&
- !lookup->GetTransitionDetails(receiver->map()).IsReadOnly();
+ if (!lookup->IsTransition()) return false;
+ PropertyDetails target_details =
+ lookup->GetTransitionDetails(receiver->map());
+ if (target_details.IsReadOnly()) return false;
+ return value->FitsRepresentation(target_details.representation());
}
@@ -1498,6 +1567,10 @@ MaybeObject* StoreIC::Store(State state,
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
+
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
@@ -1544,7 +1617,7 @@ MaybeObject* StoreIC::Store(State state,
}
LookupResult lookup(isolate());
- if (LookupForWrite(receiver, name, &lookup)) {
+ if (LookupForWrite(receiver, name, value, &lookup)) {
if (FLAG_use_ic) {
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
}
@@ -1953,6 +2026,9 @@ MaybeObject* KeyedStoreIC::Store(State state,
if (miss_mode != MISS_FORCE_GENERIC) {
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->map()->is_deprecated()) {
+ JSObject::MigrateInstance(receiver);
+ }
bool key_is_smi_like = key->IsSmi() ||
(FLAG_compiled_keyed_stores && !key->ToSmi()->IsFailure());
if (receiver->elements()->map() ==
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/json-parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698