Update deprecated maps before generating optimized code.
Review URL: https://chromiumcodereview.appspot.com/14847008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14522 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8b25614aa9
commit
fd9c82a618
@ -277,6 +277,14 @@ class SmallMapList {
|
||||
bool is_empty() const { return list_.is_empty(); }
|
||||
int length() const { return list_.length(); }
|
||||
|
||||
void AddMapIfMissing(Handle<Map> map, Zone* zone) {
|
||||
map = Map::CurrentMapForDeprecated(map);
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
if (at(i).is_identical_to(map)) return;
|
||||
}
|
||||
Add(map, zone);
|
||||
}
|
||||
|
||||
void Add(Handle<Map> handle, Zone* zone) {
|
||||
list_.Add(handle.location(), zone);
|
||||
}
|
||||
|
@ -3610,6 +3610,12 @@ 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(),
|
||||
|
@ -7280,7 +7280,7 @@ MaybeObject* DescriptorArray::Merge(int verbatim,
|
||||
// Allocate a new descriptor array large enough to hold the required
|
||||
// descriptors, with minimally the exact same size as this descriptor array.
|
||||
MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
|
||||
new_size, Max(new_size, number_of_descriptors()) - new_size);
|
||||
new_size, Max(new_size, other->number_of_descriptors()) - new_size);
|
||||
if (!maybe_descriptors->To(&result)) return maybe_descriptors;
|
||||
ASSERT(result->length() > length() ||
|
||||
result->NumberOfSlackDescriptors() > 0 ||
|
||||
|
@ -5344,6 +5344,12 @@ class Map: public HeapObject {
|
||||
inline void deprecate();
|
||||
inline bool is_deprecated();
|
||||
inline bool CanBeDeprecated();
|
||||
// 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);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
|
||||
MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
|
||||
|
@ -1059,45 +1059,40 @@ void StubCache::Clear() {
|
||||
|
||||
|
||||
void StubCache::CollectMatchingMaps(SmallMapList* types,
|
||||
Name* name,
|
||||
Handle<Name> name,
|
||||
Code::Flags flags,
|
||||
Handle<Context> native_context,
|
||||
Zone* zone) {
|
||||
for (int i = 0; i < kPrimaryTableSize; i++) {
|
||||
if (primary_[i].key == name) {
|
||||
if (primary_[i].key == *name) {
|
||||
Map* map = primary_[i].map;
|
||||
// Map can be NULL, if the stub is constant function call
|
||||
// with a primitive receiver.
|
||||
if (map == NULL) continue;
|
||||
|
||||
int offset = PrimaryOffset(name, flags, map);
|
||||
int offset = PrimaryOffset(*name, flags, map);
|
||||
if (entry(primary_, offset) == &primary_[i] &&
|
||||
!TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
|
||||
types->Add(Handle<Map>(map), zone);
|
||||
types->AddMapIfMissing(Handle<Map>(map), zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kSecondaryTableSize; i++) {
|
||||
if (secondary_[i].key == name) {
|
||||
if (secondary_[i].key == *name) {
|
||||
Map* map = secondary_[i].map;
|
||||
// Map can be NULL, if the stub is constant function call
|
||||
// with a primitive receiver.
|
||||
if (map == NULL) continue;
|
||||
|
||||
// Lookup in primary table and skip duplicates.
|
||||
int primary_offset = PrimaryOffset(name, flags, map);
|
||||
Entry* primary_entry = entry(primary_, primary_offset);
|
||||
if (primary_entry->key == name) {
|
||||
Map* primary_map = primary_entry->map;
|
||||
if (map == primary_map) continue;
|
||||
}
|
||||
int primary_offset = PrimaryOffset(*name, flags, map);
|
||||
|
||||
// Lookup in secondary table and add matches.
|
||||
int offset = SecondaryOffset(name, flags, primary_offset);
|
||||
int offset = SecondaryOffset(*name, flags, primary_offset);
|
||||
if (entry(secondary_, offset) == &secondary_[i] &&
|
||||
!TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
|
||||
types->Add(Handle<Map>(map), zone);
|
||||
types->AddMapIfMissing(Handle<Map>(map), zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ class StubCache {
|
||||
|
||||
// Collect all maps that match the name and flags.
|
||||
void CollectMatchingMaps(SmallMapList* types,
|
||||
Name* name,
|
||||
Handle<Name> name,
|
||||
Code::Flags flags,
|
||||
Handle<Context> native_context,
|
||||
Zone* zone);
|
||||
|
@ -539,15 +539,6 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
|
||||
}
|
||||
|
||||
|
||||
static void AddMapIfMissing(Handle<Map> map, SmallMapList* list,
|
||||
Zone* zone) {
|
||||
for (int i = 0; i < list->length(); ++i) {
|
||||
if (list->at(i).is_identical_to(map)) return;
|
||||
}
|
||||
list->Add(map, zone);
|
||||
}
|
||||
|
||||
|
||||
void TypeFeedbackOracle::CollectPolymorphicMaps(Handle<Code> code,
|
||||
SmallMapList* types) {
|
||||
MapHandleList maps;
|
||||
@ -556,7 +547,7 @@ void TypeFeedbackOracle::CollectPolymorphicMaps(Handle<Code> code,
|
||||
for (int i = 0; i < maps.length(); i++) {
|
||||
Handle<Map> map(maps.at(i));
|
||||
if (!CanRetainOtherContext(*map, *native_context_)) {
|
||||
AddMapIfMissing(map, types, zone());
|
||||
types->AddMapIfMissing(map, zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -574,7 +565,7 @@ void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
|
||||
// we need a generic store (or load) here.
|
||||
ASSERT(Handle<Code>::cast(object)->ic_state() == GENERIC);
|
||||
} else if (object->IsMap()) {
|
||||
types->Add(Handle<Map>::cast(object), zone());
|
||||
types->AddMapIfMissing(Handle<Map>::cast(object), zone());
|
||||
} else if (Handle<Code>::cast(object)->ic_state() == POLYMORPHIC) {
|
||||
CollectPolymorphicMaps(Handle<Code>::cast(object), types);
|
||||
} else if (FLAG_collect_megamorphic_maps_from_stub_cache &&
|
||||
@ -582,7 +573,7 @@ void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
|
||||
types->Reserve(4, zone());
|
||||
ASSERT(object->IsCode());
|
||||
isolate_->stub_cache()->CollectMatchingMaps(types,
|
||||
*name,
|
||||
name,
|
||||
flags,
|
||||
native_context_,
|
||||
zone());
|
||||
|
Loading…
Reference in New Issue
Block a user