| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 1daf1ebc0297df1a7e89257ed80d2a2d853841c8..41b6cf18f7f3288e6967f5372c4e99c9f763327f 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -4658,48 +4658,30 @@ PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
|
| }
|
|
|
|
|
| -Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache,
|
| - Handle<Map> fast_map,
|
| - PropertyNormalizationMode mode) {
|
| - int index = fast_map->Hash() % kEntries;
|
| - Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
|
| - if (result->IsMap() &&
|
| - Handle<Map>::cast(result)->EquivalentToForNormalization(
|
| - *fast_map, mode)) {
|
| -#ifdef VERIFY_HEAP
|
| - if (FLAG_verify_heap) {
|
| - Handle<Map>::cast(result)->SharedMapVerify();
|
| - }
|
| -#endif
|
| -#ifdef ENABLE_SLOW_ASSERTS
|
| - if (FLAG_enable_slow_asserts) {
|
| - // The cached map should match newly created normalized map bit-by-bit,
|
| - // except for the code cache, which can contain some ics which can be
|
| - // applied to the shared map.
|
| - Handle<Map> fresh = Map::CopyNormalized(
|
| - fast_map, mode, SHARED_NORMALIZED_MAP);
|
| +Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
|
| + Handle<FixedArray> array(
|
| + isolate->factory()->NewFixedArray(kEntries, TENURED));
|
| + return Handle<NormalizedMapCache>::cast(array);
|
| +}
|
|
|
| - ASSERT(memcmp(fresh->address(),
|
| - Handle<Map>::cast(result)->address(),
|
| - Map::kCodeCacheOffset) == 0);
|
| - STATIC_ASSERT(Map::kDependentCodeOffset ==
|
| - Map::kCodeCacheOffset + kPointerSize);
|
| - int offset = Map::kDependentCodeOffset + kPointerSize;
|
| - ASSERT(memcmp(fresh->address() + offset,
|
| - Handle<Map>::cast(result)->address() + offset,
|
| - Map::kSize - offset) == 0);
|
| - }
|
| -#endif
|
| - return Handle<Map>::cast(result);
|
| +
|
| +MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
|
| + PropertyNormalizationMode mode) {
|
| + DisallowHeapAllocation no_gc;
|
| + Object* value = FixedArray::get(GetIndex(fast_map));
|
| + if (!value->IsMap() ||
|
| + !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
|
| + return MaybeHandle<Map>();
|
| }
|
| + return handle(Map::cast(value));
|
| +}
|
|
|
| - Isolate* isolate = cache->GetIsolate();
|
| - Handle<Map> map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
|
| - ASSERT(map->is_dictionary_map());
|
| - cache->set(index, *map);
|
| - isolate->counters()->normalized_maps()->Increment();
|
|
|
| - return map;
|
| +void NormalizedMapCache::Set(Handle<Map> fast_map,
|
| + Handle<Map> normalized_map) {
|
| + DisallowHeapAllocation no_gc;
|
| + ASSERT(normalized_map->is_dictionary_map());
|
| + FixedArray::set(GetIndex(fast_map), *normalized_map);
|
| }
|
|
|
|
|
| @@ -4732,6 +4714,7 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
|
| Isolate* isolate = object->GetIsolate();
|
| HandleScope scope(isolate);
|
| Handle<Map> map(object->map());
|
| + Handle<Map> new_map = Map::Normalize(map, mode);
|
|
|
| // Allocate new content.
|
| int real_size = map->NumberOfOwnDescriptors();
|
| @@ -4786,12 +4769,6 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
|
| // Copy the next enumeration index from instance descriptor.
|
| dictionary->SetNextEnumerationIndex(real_size + 1);
|
|
|
| - Handle<NormalizedMapCache> cache(
|
| - isolate->context()->native_context()->normalized_map_cache());
|
| - Handle<Map> new_map = NormalizedMapCache::Get(
|
| - cache, handle(object->map()), mode);
|
| - ASSERT(new_map->is_dictionary_map());
|
| -
|
| // From here on we cannot fail and we shouldn't GC anymore.
|
| DisallowHeapAllocation no_allocation;
|
|
|
| @@ -4810,8 +4787,6 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
|
| // the left-over space to avoid races with the sweeper thread.
|
| object->synchronized_set_map(*new_map);
|
|
|
| - map->NotifyLeafMapLayoutChange();
|
| -
|
| object->set_properties(*dictionary);
|
|
|
| isolate->counters()->props_to_dictionary()->Increment();
|
| @@ -7238,6 +7213,50 @@ Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
|
| }
|
|
|
|
|
| +Handle<Map> Map::Normalize(Handle<Map> fast_map,
|
| + PropertyNormalizationMode mode) {
|
| + ASSERT(!fast_map->is_dictionary_map());
|
| +
|
| + Isolate* isolate = fast_map->GetIsolate();
|
| + Handle<NormalizedMapCache> cache(
|
| + isolate->context()->native_context()->normalized_map_cache());
|
| +
|
| + Handle<Map> new_map;
|
| + if (cache->Get(fast_map, mode).ToHandle(&new_map)) {
|
| +#ifdef VERIFY_HEAP
|
| + if (FLAG_verify_heap) {
|
| + new_map->SharedMapVerify();
|
| + }
|
| +#endif
|
| +#ifdef ENABLE_SLOW_ASSERTS
|
| + if (FLAG_enable_slow_asserts) {
|
| + // The cached map should match newly created normalized map bit-by-bit,
|
| + // except for the code cache, which can contain some ics which can be
|
| + // applied to the shared map.
|
| + Handle<Map> fresh = Map::CopyNormalized(
|
| + fast_map, mode, SHARED_NORMALIZED_MAP);
|
| +
|
| + ASSERT(memcmp(fresh->address(),
|
| + new_map->address(),
|
| + Map::kCodeCacheOffset) == 0);
|
| + STATIC_ASSERT(Map::kDependentCodeOffset ==
|
| + Map::kCodeCacheOffset + kPointerSize);
|
| + int offset = Map::kDependentCodeOffset + kPointerSize;
|
| + ASSERT(memcmp(fresh->address() + offset,
|
| + new_map->address() + offset,
|
| + Map::kSize - offset) == 0);
|
| + }
|
| +#endif
|
| + } else {
|
| + new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
|
| + cache->Set(fast_map, new_map);
|
| + isolate->counters()->normalized_maps()->Increment();
|
| + }
|
| + fast_map->NotifyLeafMapLayoutChange();
|
| + return new_map;
|
| +}
|
| +
|
| +
|
| Handle<Map> Map::CopyNormalized(Handle<Map> map,
|
| PropertyNormalizationMode mode,
|
| NormalizedMapSharingMode sharing) {
|
|
|