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

Side by Side Diff: src/objects.cc

Issue 263663002: Map::Normalize() introduced as single entry point for map normalization and Map::NotifyLeafMapLayou… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing review comments Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #include "accessors.h" 7 #include "accessors.h"
8 #include "allocation-site-scopes.h" 8 #include "allocation-site-scopes.h"
9 #include "api.h" 9 #include "api.h"
10 #include "arguments.h" 10 #include "arguments.h"
(...skipping 4640 matching lines...) Expand 10 before | Expand all | Expand 10 after
4651 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. 4651 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
4652 return JSProxy::GetElementAttributeWithHandler( 4652 return JSProxy::GetElementAttributeWithHandler(
4653 Handle<JSProxy>::cast(proto), receiver, index); 4653 Handle<JSProxy>::cast(proto), receiver, index);
4654 } 4654 }
4655 if (proto->IsNull()) return ABSENT; 4655 if (proto->IsNull()) return ABSENT;
4656 return GetElementAttributeWithReceiver( 4656 return GetElementAttributeWithReceiver(
4657 Handle<JSObject>::cast(proto), receiver, index, true); 4657 Handle<JSObject>::cast(proto), receiver, index, true);
4658 } 4658 }
4659 4659
4660 4660
4661 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, 4661 Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
4662 Handle<Map> fast_map, 4662 Handle<FixedArray> array(
4663 PropertyNormalizationMode mode) { 4663 isolate->factory()->NewFixedArray(kEntries, TENURED));
4664 int index = fast_map->Hash() % kEntries; 4664 return Handle<NormalizedMapCache>::cast(array);
4665 Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
4666 if (result->IsMap() &&
4667 Handle<Map>::cast(result)->EquivalentToForNormalization(
4668 *fast_map, mode)) {
4669 #ifdef VERIFY_HEAP
4670 if (FLAG_verify_heap) {
4671 Handle<Map>::cast(result)->SharedMapVerify();
4672 }
4673 #endif
4674 #ifdef ENABLE_SLOW_ASSERTS
4675 if (FLAG_enable_slow_asserts) {
4676 // The cached map should match newly created normalized map bit-by-bit,
4677 // except for the code cache, which can contain some ics which can be
4678 // applied to the shared map.
4679 Handle<Map> fresh = Map::CopyNormalized(
4680 fast_map, mode, SHARED_NORMALIZED_MAP);
4681
4682 ASSERT(memcmp(fresh->address(),
4683 Handle<Map>::cast(result)->address(),
4684 Map::kCodeCacheOffset) == 0);
4685 STATIC_ASSERT(Map::kDependentCodeOffset ==
4686 Map::kCodeCacheOffset + kPointerSize);
4687 int offset = Map::kDependentCodeOffset + kPointerSize;
4688 ASSERT(memcmp(fresh->address() + offset,
4689 Handle<Map>::cast(result)->address() + offset,
4690 Map::kSize - offset) == 0);
4691 }
4692 #endif
4693 return Handle<Map>::cast(result);
4694 }
4695
4696 Isolate* isolate = cache->GetIsolate();
4697 Handle<Map> map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
4698 ASSERT(map->is_dictionary_map());
4699 cache->set(index, *map);
4700 isolate->counters()->normalized_maps()->Increment();
4701
4702 return map;
4703 } 4665 }
4704 4666
4705 4667
4668 MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
4669 PropertyNormalizationMode mode) {
4670 DisallowHeapAllocation no_gc;
4671 Object* value = FixedArray::get(GetIndex(fast_map));
4672 if (!value->IsMap() ||
4673 !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
4674 return MaybeHandle<Map>();
4675 }
4676 return handle(Map::cast(value));
4677 }
4678
4679
4680 void NormalizedMapCache::Set(Handle<Map> fast_map,
4681 Handle<Map> normalized_map) {
4682 DisallowHeapAllocation no_gc;
4683 ASSERT(normalized_map->is_dictionary_map());
4684 FixedArray::set(GetIndex(fast_map), *normalized_map);
4685 }
4686
4687
4706 void NormalizedMapCache::Clear() { 4688 void NormalizedMapCache::Clear() {
4707 int entries = length(); 4689 int entries = length();
4708 for (int i = 0; i != entries; i++) { 4690 for (int i = 0; i != entries; i++) {
4709 set_undefined(i); 4691 set_undefined(i);
4710 } 4692 }
4711 } 4693 }
4712 4694
4713 4695
4714 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, 4696 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
4715 Handle<Name> name, 4697 Handle<Name> name,
4716 Handle<Code> code) { 4698 Handle<Code> code) {
4717 Handle<Map> map(object->map()); 4699 Handle<Map> map(object->map());
4718 Map::UpdateCodeCache(map, name, code); 4700 Map::UpdateCodeCache(map, name, code);
4719 } 4701 }
4720 4702
4721 4703
4722 void JSObject::NormalizeProperties(Handle<JSObject> object, 4704 void JSObject::NormalizeProperties(Handle<JSObject> object,
4723 PropertyNormalizationMode mode, 4705 PropertyNormalizationMode mode,
4724 int expected_additional_properties) { 4706 int expected_additional_properties) {
4725 if (!object->HasFastProperties()) return; 4707 if (!object->HasFastProperties()) return;
4726 4708
4727 // The global object is always normalized. 4709 // The global object is always normalized.
4728 ASSERT(!object->IsGlobalObject()); 4710 ASSERT(!object->IsGlobalObject());
4729 // JSGlobalProxy must never be normalized 4711 // JSGlobalProxy must never be normalized
4730 ASSERT(!object->IsJSGlobalProxy()); 4712 ASSERT(!object->IsJSGlobalProxy());
4731 4713
4732 Isolate* isolate = object->GetIsolate(); 4714 Isolate* isolate = object->GetIsolate();
4733 HandleScope scope(isolate); 4715 HandleScope scope(isolate);
4734 Handle<Map> map(object->map()); 4716 Handle<Map> map(object->map());
4717 Handle<Map> new_map = Map::Normalize(map, mode);
4735 4718
4736 // Allocate new content. 4719 // Allocate new content.
4737 int real_size = map->NumberOfOwnDescriptors(); 4720 int real_size = map->NumberOfOwnDescriptors();
4738 int property_count = real_size; 4721 int property_count = real_size;
4739 if (expected_additional_properties > 0) { 4722 if (expected_additional_properties > 0) {
4740 property_count += expected_additional_properties; 4723 property_count += expected_additional_properties;
4741 } else { 4724 } else {
4742 property_count += 2; // Make space for two more properties. 4725 property_count += 2; // Make space for two more properties.
4743 } 4726 }
4744 Handle<NameDictionary> dictionary = 4727 Handle<NameDictionary> dictionary =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4779 case NORMAL: 4762 case NORMAL:
4780 case NONEXISTENT: 4763 case NONEXISTENT:
4781 UNREACHABLE(); 4764 UNREACHABLE();
4782 break; 4765 break;
4783 } 4766 }
4784 } 4767 }
4785 4768
4786 // Copy the next enumeration index from instance descriptor. 4769 // Copy the next enumeration index from instance descriptor.
4787 dictionary->SetNextEnumerationIndex(real_size + 1); 4770 dictionary->SetNextEnumerationIndex(real_size + 1);
4788 4771
4789 Handle<NormalizedMapCache> cache(
4790 isolate->context()->native_context()->normalized_map_cache());
4791 Handle<Map> new_map = NormalizedMapCache::Get(
4792 cache, handle(object->map()), mode);
4793 ASSERT(new_map->is_dictionary_map());
4794
4795 // From here on we cannot fail and we shouldn't GC anymore. 4772 // From here on we cannot fail and we shouldn't GC anymore.
4796 DisallowHeapAllocation no_allocation; 4773 DisallowHeapAllocation no_allocation;
4797 4774
4798 // Resize the object in the heap if necessary. 4775 // Resize the object in the heap if necessary.
4799 int new_instance_size = new_map->instance_size(); 4776 int new_instance_size = new_map->instance_size();
4800 int instance_size_delta = map->instance_size() - new_instance_size; 4777 int instance_size_delta = map->instance_size() - new_instance_size;
4801 ASSERT(instance_size_delta >= 0); 4778 ASSERT(instance_size_delta >= 0);
4802 Heap* heap = isolate->heap(); 4779 Heap* heap = isolate->heap();
4803 heap->CreateFillerObjectAt(object->address() + new_instance_size, 4780 heap->CreateFillerObjectAt(object->address() + new_instance_size,
4804 instance_size_delta); 4781 instance_size_delta);
4805 heap->AdjustLiveBytes(object->address(), 4782 heap->AdjustLiveBytes(object->address(),
4806 -instance_size_delta, 4783 -instance_size_delta,
4807 Heap::FROM_MUTATOR); 4784 Heap::FROM_MUTATOR);
4808 4785
4809 // We are storing the new map using release store after creating a filler for 4786 // We are storing the new map using release store after creating a filler for
4810 // the left-over space to avoid races with the sweeper thread. 4787 // the left-over space to avoid races with the sweeper thread.
4811 object->synchronized_set_map(*new_map); 4788 object->synchronized_set_map(*new_map);
4812 4789
4813 map->NotifyLeafMapLayoutChange();
4814
4815 object->set_properties(*dictionary); 4790 object->set_properties(*dictionary);
4816 4791
4817 isolate->counters()->props_to_dictionary()->Increment(); 4792 isolate->counters()->props_to_dictionary()->Increment();
4818 4793
4819 #ifdef DEBUG 4794 #ifdef DEBUG
4820 if (FLAG_trace_normalization) { 4795 if (FLAG_trace_normalization) {
4821 PrintF("Object properties have been normalized:\n"); 4796 PrintF("Object properties have been normalized:\n");
4822 object->Print(); 4797 object->Print();
4823 } 4798 }
4824 #endif 4799 #endif
(...skipping 2406 matching lines...) Expand 10 before | Expand all | Expand 10 after
7231 kInvalidEnumCacheSentinel); 7206 kInvalidEnumCacheSentinel);
7232 new_bit_field3 = Deprecated::update(new_bit_field3, false); 7207 new_bit_field3 = Deprecated::update(new_bit_field3, false);
7233 if (!map->is_dictionary_map()) { 7208 if (!map->is_dictionary_map()) {
7234 new_bit_field3 = IsUnstable::update(new_bit_field3, false); 7209 new_bit_field3 = IsUnstable::update(new_bit_field3, false);
7235 } 7210 }
7236 result->set_bit_field3(new_bit_field3); 7211 result->set_bit_field3(new_bit_field3);
7237 return result; 7212 return result;
7238 } 7213 }
7239 7214
7240 7215
7216 Handle<Map> Map::Normalize(Handle<Map> fast_map,
7217 PropertyNormalizationMode mode) {
7218 ASSERT(!fast_map->is_dictionary_map());
7219
7220 Isolate* isolate = fast_map->GetIsolate();
7221 Handle<NormalizedMapCache> cache(
7222 isolate->context()->native_context()->normalized_map_cache());
7223
7224 Handle<Map> new_map;
7225 if (cache->Get(fast_map, mode).ToHandle(&new_map)) {
7226 #ifdef VERIFY_HEAP
7227 if (FLAG_verify_heap) {
7228 new_map->SharedMapVerify();
7229 }
7230 #endif
7231 #ifdef ENABLE_SLOW_ASSERTS
7232 if (FLAG_enable_slow_asserts) {
7233 // The cached map should match newly created normalized map bit-by-bit,
7234 // except for the code cache, which can contain some ics which can be
7235 // applied to the shared map.
7236 Handle<Map> fresh = Map::CopyNormalized(
7237 fast_map, mode, SHARED_NORMALIZED_MAP);
7238
7239 ASSERT(memcmp(fresh->address(),
7240 new_map->address(),
7241 Map::kCodeCacheOffset) == 0);
7242 STATIC_ASSERT(Map::kDependentCodeOffset ==
7243 Map::kCodeCacheOffset + kPointerSize);
7244 int offset = Map::kDependentCodeOffset + kPointerSize;
7245 ASSERT(memcmp(fresh->address() + offset,
7246 new_map->address() + offset,
7247 Map::kSize - offset) == 0);
7248 }
7249 #endif
7250 } else {
7251 new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
7252 cache->Set(fast_map, new_map);
7253 isolate->counters()->normalized_maps()->Increment();
7254 }
7255 fast_map->NotifyLeafMapLayoutChange();
7256 return new_map;
7257 }
7258
7259
7241 Handle<Map> Map::CopyNormalized(Handle<Map> map, 7260 Handle<Map> Map::CopyNormalized(Handle<Map> map,
7242 PropertyNormalizationMode mode, 7261 PropertyNormalizationMode mode,
7243 NormalizedMapSharingMode sharing) { 7262 NormalizedMapSharingMode sharing) {
7244 int new_instance_size = map->instance_size(); 7263 int new_instance_size = map->instance_size();
7245 if (mode == CLEAR_INOBJECT_PROPERTIES) { 7264 if (mode == CLEAR_INOBJECT_PROPERTIES) {
7246 new_instance_size -= map->inobject_properties() * kPointerSize; 7265 new_instance_size -= map->inobject_properties() * kPointerSize;
7247 } 7266 }
7248 7267
7249 Handle<Map> result = RawCopy(map, new_instance_size); 7268 Handle<Map> result = RawCopy(map, new_instance_size);
7250 7269
(...skipping 9959 matching lines...) Expand 10 before | Expand all | Expand 10 after
17210 #define ERROR_MESSAGES_TEXTS(C, T) T, 17229 #define ERROR_MESSAGES_TEXTS(C, T) T,
17211 static const char* error_messages_[] = { 17230 static const char* error_messages_[] = {
17212 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17231 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17213 }; 17232 };
17214 #undef ERROR_MESSAGES_TEXTS 17233 #undef ERROR_MESSAGES_TEXTS
17215 return error_messages_[reason]; 17234 return error_messages_[reason];
17216 } 17235 }
17217 17236
17218 17237
17219 } } // namespace v8::internal 17238 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698