Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |