Don't create new maps in CurrentMapForDeprecated.
R=yangguo@chromium.org Review URL: https://chromiumcodereview.appspot.com/15358005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14728 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
467b16fd3a
commit
9f32d94cb3
@ -278,7 +278,9 @@ class SmallMapList {
|
||||
int length() const { return list_.length(); }
|
||||
|
||||
void AddMapIfMissing(Handle<Map> map, Zone* zone) {
|
||||
map = Map::CurrentMapForDeprecated(map);
|
||||
Map* updated = map->CurrentMapForDeprecated();
|
||||
if (updated == NULL) return;
|
||||
map = Handle<Map>(updated);
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
if (at(i).is_identical_to(map)) return;
|
||||
}
|
||||
|
@ -1832,7 +1832,7 @@ void HGraphBuilder::BuildCompareNil(
|
||||
} else {
|
||||
if_nil.Then();
|
||||
if_nil.Else();
|
||||
if (types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
|
||||
if (!map.is_null() && types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
|
||||
BuildCheckNonSmi(value);
|
||||
// For ICs, the map checked below is a sentinel map that gets replaced by
|
||||
// the monomorphic map when the code is used as a template to generate a
|
||||
|
@ -3624,12 +3624,6 @@ bool Map::CanBeDeprecated() {
|
||||
}
|
||||
|
||||
|
||||
Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
|
||||
if (!map->is_deprecated()) return map;
|
||||
return GeneralizeRepresentation(map, 0, Representation::Smi());
|
||||
}
|
||||
|
||||
|
||||
void Map::NotifyLeafMapLayoutChange() {
|
||||
dependent_code()->DeoptimizeDependentCodeGroup(
|
||||
GetIsolate(),
|
||||
|
@ -2537,6 +2537,7 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
int descriptors = old_map->NumberOfOwnDescriptors();
|
||||
Map* root_map = old_map->FindRootMap();
|
||||
|
||||
// Check the state of the root map.
|
||||
if (!old_map->EquivalentToForTransition(root_map)) {
|
||||
return CopyGeneralizeAllRepresentations();
|
||||
}
|
||||
@ -2547,7 +2548,6 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
verbatim, descriptors, old_descriptors);
|
||||
if (updated == NULL) return CopyGeneralizeAllRepresentations();
|
||||
|
||||
// Check the state of the root map.
|
||||
DescriptorArray* updated_descriptors = updated->instance_descriptors();
|
||||
|
||||
int valid = updated->NumberOfOwnDescriptors();
|
||||
@ -2624,6 +2624,34 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
}
|
||||
|
||||
|
||||
Map* Map::CurrentMapForDeprecated() {
|
||||
AssertNoAllocation no_allocation;
|
||||
if (!is_deprecated()) return this;
|
||||
|
||||
DescriptorArray* old_descriptors = instance_descriptors();
|
||||
|
||||
int descriptors = NumberOfOwnDescriptors();
|
||||
Map* root_map = FindRootMap();
|
||||
|
||||
// Check the state of the root map.
|
||||
if (!EquivalentToForTransition(root_map)) return NULL;
|
||||
int verbatim = root_map->NumberOfOwnDescriptors();
|
||||
|
||||
Map* updated = root_map->FindUpdatedMap(
|
||||
verbatim, descriptors, old_descriptors);
|
||||
if (updated == NULL) return NULL;
|
||||
|
||||
DescriptorArray* updated_descriptors = updated->instance_descriptors();
|
||||
int valid = updated->NumberOfOwnDescriptors();
|
||||
if (!updated_descriptors->IsMoreGeneralThan(
|
||||
verbatim, valid, descriptors, old_descriptors)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::SetPropertyWithInterceptor(
|
||||
Name* name,
|
||||
Object* value,
|
||||
|
@ -5377,9 +5377,8 @@ class Map: public HeapObject {
|
||||
// Returns a non-deprecated version of the input. If the input was not
|
||||
// deprecated, it is directly returned. Otherwise, the non-deprecated version
|
||||
// is found by re-transitioning from the root of the transition tree using the
|
||||
// descriptor array of the map. New maps (and transitions) may be created if
|
||||
// no new (more general) version exists.
|
||||
static inline Handle<Map> CurrentMapForDeprecated(Handle<Map> map);
|
||||
// descriptor array of the map. Returns NULL if no updated map is found.
|
||||
Map* CurrentMapForDeprecated();
|
||||
|
||||
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
|
||||
MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
|
||||
|
@ -105,6 +105,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
|
||||
Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
|
||||
if (!preliminary_checks) return false;
|
||||
Map* map = code->FindFirstMap();
|
||||
if (map == NULL) return false;
|
||||
map = map->CurrentMapForDeprecated();
|
||||
return map != NULL && !CanRetainOtherContext(map, *native_context_);
|
||||
}
|
||||
return false;
|
||||
@ -136,6 +138,8 @@ bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
|
||||
Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
|
||||
if (!preliminary_checks) return false;
|
||||
Map* map = code->FindFirstMap();
|
||||
if (map == NULL) return false;
|
||||
map = map->CurrentMapForDeprecated();
|
||||
return map != NULL && !CanRetainOtherContext(map, *native_context_);
|
||||
}
|
||||
return false;
|
||||
@ -192,14 +196,12 @@ Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
|
||||
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
|
||||
if (map_or_code->IsCode()) {
|
||||
Handle<Code> code = Handle<Code>::cast(map_or_code);
|
||||
Handle<Map> first_map(code->FindFirstMap());
|
||||
ASSERT(!first_map.is_null());
|
||||
first_map = Map::CurrentMapForDeprecated(first_map);
|
||||
return CanRetainOtherContext(*first_map, *native_context_)
|
||||
Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
|
||||
return map == NULL || CanRetainOtherContext(map, *native_context_)
|
||||
? Handle<Map>::null()
|
||||
: first_map;
|
||||
: Handle<Map>(map);
|
||||
}
|
||||
return Map::CurrentMapForDeprecated(Handle<Map>::cast(map_or_code));
|
||||
return Handle<Map>::cast(map_or_code);
|
||||
}
|
||||
|
||||
|
||||
@ -209,14 +211,12 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
|
||||
Handle<Object> map_or_code = GetInfo(ast_id);
|
||||
if (map_or_code->IsCode()) {
|
||||
Handle<Code> code = Handle<Code>::cast(map_or_code);
|
||||
Handle<Map> first_map(code->FindFirstMap());
|
||||
ASSERT(!first_map.is_null());
|
||||
first_map = Map::CurrentMapForDeprecated(first_map);
|
||||
return CanRetainOtherContext(*first_map, *native_context_)
|
||||
Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
|
||||
return map == NULL || CanRetainOtherContext(map, *native_context_)
|
||||
? Handle<Map>::null()
|
||||
: first_map;
|
||||
: Handle<Map>(map);
|
||||
}
|
||||
return Map::CurrentMapForDeprecated(Handle<Map>::cast(map_or_code));
|
||||
return Handle<Map>::cast(map_or_code);
|
||||
}
|
||||
|
||||
|
||||
@ -224,10 +224,15 @@ Handle<Map> TypeFeedbackOracle::CompareNilMonomorphicReceiverType(
|
||||
TypeFeedbackId id) {
|
||||
Handle<Object> maybe_code = GetInfo(id);
|
||||
if (maybe_code->IsCode()) {
|
||||
Map* first_map = Handle<Code>::cast(maybe_code)->FindFirstMap();
|
||||
if (first_map != NULL) {
|
||||
return Map::CurrentMapForDeprecated(Handle<Map>(first_map));
|
||||
}
|
||||
Map* map = Handle<Code>::cast(maybe_code)->FindFirstMap();
|
||||
if (map == NULL) return Handle<Map>();
|
||||
map = map->CurrentMapForDeprecated();
|
||||
return map == NULL || CanRetainOtherContext(map, *native_context_)
|
||||
? Handle<Map>()
|
||||
: Handle<Map>(map);
|
||||
} else if (maybe_code->IsMap()) {
|
||||
ASSERT(!Handle<Map>::cast(maybe_code)->is_deprecated());
|
||||
return Handle<Map>::cast(maybe_code);
|
||||
}
|
||||
return Handle<Map>();
|
||||
}
|
||||
@ -351,8 +356,7 @@ ElementsKind TypeFeedbackOracle::GetCallNewElementsKind(CallNew* expr) {
|
||||
Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
|
||||
ObjectLiteral::Property* prop) {
|
||||
ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
|
||||
return Map::CurrentMapForDeprecated(
|
||||
Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId())));
|
||||
return Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId()));
|
||||
}
|
||||
|
||||
|
||||
@ -431,12 +435,10 @@ Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
|
||||
if (state != CompareIC::KNOWN_OBJECT) {
|
||||
return Handle<Map>::null();
|
||||
}
|
||||
Handle<Map> first_map(code->FindFirstMap());
|
||||
ASSERT(!first_map.is_null());
|
||||
first_map = Map::CurrentMapForDeprecated(first_map);
|
||||
return CanRetainOtherContext(*first_map, *native_context_)
|
||||
Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
|
||||
return map == NULL || CanRetainOtherContext(map, *native_context_)
|
||||
? Handle<Map>::null()
|
||||
: first_map;
|
||||
: Handle<Map>(map);
|
||||
}
|
||||
|
||||
|
||||
@ -723,7 +725,8 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
|
||||
SetInfo(ast_id, static_cast<Object*>(target));
|
||||
} else if (!CanRetainOtherContext(Map::cast(map),
|
||||
*native_context_)) {
|
||||
SetInfo(ast_id, map);
|
||||
Map* feedback = Map::cast(map)->CurrentMapForDeprecated();
|
||||
if (feedback != NULL) SetInfo(ast_id, feedback);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user