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

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 notes 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 DisallowHeapAllocation no_gc;
4670 Object* value = FixedArray::get(GetIndex(fast_map));
4671 if (!value->IsMap()) return MaybeHandle<Map>();
4672 return handle(Map::cast(value));
4673 }
4674
4675
4676 void NormalizedMapCache::Set(Handle<Map> fast_map,
4677 Handle<Map> normalized_map) {
4678 DisallowHeapAllocation no_gc;
4679 ASSERT(normalized_map->is_dictionary_map());
4680 FixedArray::set(GetIndex(fast_map), *normalized_map);
4681 }
4682
4683
4706 void NormalizedMapCache::Clear() { 4684 void NormalizedMapCache::Clear() {
4707 int entries = length(); 4685 int entries = length();
4708 for (int i = 0; i != entries; i++) { 4686 for (int i = 0; i != entries; i++) {
4709 set_undefined(i); 4687 set_undefined(i);
4710 } 4688 }
4711 } 4689 }
4712 4690
4713 4691
4714 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, 4692 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
4715 Handle<Name> name, 4693 Handle<Name> name,
4716 Handle<Code> code) { 4694 Handle<Code> code) {
4717 Handle<Map> map(object->map()); 4695 Handle<Map> map(object->map());
4718 Map::UpdateCodeCache(map, name, code); 4696 Map::UpdateCodeCache(map, name, code);
4719 } 4697 }
4720 4698
4721 4699
4722 void JSObject::NormalizeProperties(Handle<JSObject> object, 4700 void JSObject::NormalizeProperties(Handle<JSObject> object,
4723 PropertyNormalizationMode mode, 4701 PropertyNormalizationMode mode,
4724 int expected_additional_properties) { 4702 int expected_additional_properties) {
4725 if (!object->HasFastProperties()) return; 4703 if (!object->HasFastProperties()) return;
4726 4704
4727 // The global object is always normalized. 4705 // The global object is always normalized.
4728 ASSERT(!object->IsGlobalObject()); 4706 ASSERT(!object->IsGlobalObject());
4729 // JSGlobalProxy must never be normalized 4707 // JSGlobalProxy must never be normalized
4730 ASSERT(!object->IsJSGlobalProxy()); 4708 ASSERT(!object->IsJSGlobalProxy());
4731 4709
4732 Isolate* isolate = object->GetIsolate(); 4710 Isolate* isolate = object->GetIsolate();
4733 HandleScope scope(isolate); 4711 HandleScope scope(isolate);
4734 Handle<Map> map(object->map()); 4712 Handle<Map> map(object->map());
4713 Handle<Map> new_map = Map::Normalize(map, mode);
4735 4714
4736 // Allocate new content. 4715 // Allocate new content.
4737 int real_size = map->NumberOfOwnDescriptors(); 4716 int real_size = map->NumberOfOwnDescriptors();
4738 int property_count = real_size; 4717 int property_count = real_size;
4739 if (expected_additional_properties > 0) { 4718 if (expected_additional_properties > 0) {
4740 property_count += expected_additional_properties; 4719 property_count += expected_additional_properties;
4741 } else { 4720 } else {
4742 property_count += 2; // Make space for two more properties. 4721 property_count += 2; // Make space for two more properties.
4743 } 4722 }
4744 Handle<NameDictionary> dictionary = 4723 Handle<NameDictionary> dictionary =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4779 case NORMAL: 4758 case NORMAL:
4780 case NONEXISTENT: 4759 case NONEXISTENT:
4781 UNREACHABLE(); 4760 UNREACHABLE();
4782 break; 4761 break;
4783 } 4762 }
4784 } 4763 }
4785 4764
4786 // Copy the next enumeration index from instance descriptor. 4765 // Copy the next enumeration index from instance descriptor.
4787 dictionary->SetNextEnumerationIndex(real_size + 1); 4766 dictionary->SetNextEnumerationIndex(real_size + 1);
4788 4767
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. 4768 // From here on we cannot fail and we shouldn't GC anymore.
4796 DisallowHeapAllocation no_allocation; 4769 DisallowHeapAllocation no_allocation;
4797 4770
4798 // Resize the object in the heap if necessary. 4771 // Resize the object in the heap if necessary.
4799 int new_instance_size = new_map->instance_size(); 4772 int new_instance_size = new_map->instance_size();
4800 int instance_size_delta = map->instance_size() - new_instance_size; 4773 int instance_size_delta = map->instance_size() - new_instance_size;
4801 ASSERT(instance_size_delta >= 0); 4774 ASSERT(instance_size_delta >= 0);
4802 Heap* heap = isolate->heap(); 4775 Heap* heap = isolate->heap();
4803 heap->CreateFillerObjectAt(object->address() + new_instance_size, 4776 heap->CreateFillerObjectAt(object->address() + new_instance_size,
4804 instance_size_delta); 4777 instance_size_delta);
4805 heap->AdjustLiveBytes(object->address(), 4778 heap->AdjustLiveBytes(object->address(),
4806 -instance_size_delta, 4779 -instance_size_delta,
4807 Heap::FROM_MUTATOR); 4780 Heap::FROM_MUTATOR);
4808 4781
4809 // We are storing the new map using release store after creating a filler for 4782 // 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. 4783 // the left-over space to avoid races with the sweeper thread.
4811 object->synchronized_set_map(*new_map); 4784 object->synchronized_set_map(*new_map);
4812 4785
4813 map->NotifyLeafMapLayoutChange();
4814
4815 object->set_properties(*dictionary); 4786 object->set_properties(*dictionary);
4816 4787
4817 isolate->counters()->props_to_dictionary()->Increment(); 4788 isolate->counters()->props_to_dictionary()->Increment();
4818 4789
4819 #ifdef DEBUG 4790 #ifdef DEBUG
4820 if (FLAG_trace_normalization) { 4791 if (FLAG_trace_normalization) {
4821 PrintF("Object properties have been normalized:\n"); 4792 PrintF("Object properties have been normalized:\n");
4822 object->Print(); 4793 object->Print();
4823 } 4794 }
4824 #endif 4795 #endif
(...skipping 2406 matching lines...) Expand 10 before | Expand all | Expand 10 after
7231 kInvalidEnumCacheSentinel); 7202 kInvalidEnumCacheSentinel);
7232 new_bit_field3 = Deprecated::update(new_bit_field3, false); 7203 new_bit_field3 = Deprecated::update(new_bit_field3, false);
7233 if (!map->is_dictionary_map()) { 7204 if (!map->is_dictionary_map()) {
7234 new_bit_field3 = IsUnstable::update(new_bit_field3, false); 7205 new_bit_field3 = IsUnstable::update(new_bit_field3, false);
7235 } 7206 }
7236 result->set_bit_field3(new_bit_field3); 7207 result->set_bit_field3(new_bit_field3);
7237 return result; 7208 return result;
7238 } 7209 }
7239 7210
7240 7211
7212 Handle<Map> Map::Normalize(Handle<Map> fast_map,
7213 PropertyNormalizationMode mode) {
7214 ASSERT(!fast_map->is_dictionary_map());
7215
7216 Isolate* isolate = fast_map->GetIsolate();
7217 Handle<NormalizedMapCache> cache(
7218 isolate->context()->native_context()->normalized_map_cache());
7219
7220 Handle<Map> new_map;
7221 if (cache->Get(fast_map).ToHandle(&new_map) &&
7222 new_map->EquivalentToForNormalization(*fast_map, mode)) {
Toon Verwaest 2014/05/01 11:24:34 Seems like EquivalentToForNormalization should be
Igor Sheludko 2014/05/02 09:47:38 Done.
7223 #ifdef VERIFY_HEAP
7224 if (FLAG_verify_heap) {
7225 new_map->SharedMapVerify();
7226 }
7227 #endif
7228 #ifdef ENABLE_SLOW_ASSERTS
7229 if (FLAG_enable_slow_asserts) {
7230 // The cached map should match newly created normalized map bit-by-bit,
7231 // except for the code cache, which can contain some ics which can be
7232 // applied to the shared map.
7233 Handle<Map> fresh = Map::CopyNormalized(
7234 fast_map, mode, SHARED_NORMALIZED_MAP);
7235
7236 ASSERT(memcmp(fresh->address(),
7237 new_map->address(),
7238 Map::kCodeCacheOffset) == 0);
7239 STATIC_ASSERT(Map::kDependentCodeOffset ==
7240 Map::kCodeCacheOffset + kPointerSize);
7241 int offset = Map::kDependentCodeOffset + kPointerSize;
7242 ASSERT(memcmp(fresh->address() + offset,
7243 new_map->address() + offset,
7244 Map::kSize - offset) == 0);
7245 }
7246 #endif
7247 } else {
7248 new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
7249 cache->Set(fast_map, new_map);
7250 isolate->counters()->normalized_maps()->Increment();
7251 }
7252 fast_map->NotifyLeafMapLayoutChange();
7253 return new_map;
7254 }
7255
7256
7241 Handle<Map> Map::CopyNormalized(Handle<Map> map, 7257 Handle<Map> Map::CopyNormalized(Handle<Map> map,
7242 PropertyNormalizationMode mode, 7258 PropertyNormalizationMode mode,
7243 NormalizedMapSharingMode sharing) { 7259 NormalizedMapSharingMode sharing) {
7244 int new_instance_size = map->instance_size(); 7260 int new_instance_size = map->instance_size();
7245 if (mode == CLEAR_INOBJECT_PROPERTIES) { 7261 if (mode == CLEAR_INOBJECT_PROPERTIES) {
7246 new_instance_size -= map->inobject_properties() * kPointerSize; 7262 new_instance_size -= map->inobject_properties() * kPointerSize;
7247 } 7263 }
7248 7264
7249 Handle<Map> result = RawCopy(map, new_instance_size); 7265 Handle<Map> result = RawCopy(map, new_instance_size);
7250 7266
(...skipping 9959 matching lines...) Expand 10 before | Expand all | Expand 10 after
17210 #define ERROR_MESSAGES_TEXTS(C, T) T, 17226 #define ERROR_MESSAGES_TEXTS(C, T) T,
17211 static const char* error_messages_[] = { 17227 static const char* error_messages_[] = {
17212 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17228 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17213 }; 17229 };
17214 #undef ERROR_MESSAGES_TEXTS 17230 #undef ERROR_MESSAGES_TEXTS
17215 return error_messages_[reason]; 17231 return error_messages_[reason];
17216 } 17232 }
17217 17233
17218 17234
17219 } } // namespace v8::internal 17235 } } // 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