OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1818 static Handle<Object> NewStorageFor(Isolate* isolate, | 1818 static Handle<Object> NewStorageFor(Isolate* isolate, |
1819 Handle<Object> object, | 1819 Handle<Object> object, |
1820 Representation representation) { | 1820 Representation representation) { |
1821 Heap* heap = isolate->heap(); | 1821 Heap* heap = isolate->heap(); |
1822 CALL_HEAP_FUNCTION(isolate, | 1822 CALL_HEAP_FUNCTION(isolate, |
1823 object->AllocateNewStorageFor(heap, representation), | 1823 object->AllocateNewStorageFor(heap, representation), |
1824 Object); | 1824 Object); |
1825 } | 1825 } |
1826 | 1826 |
1827 | 1827 |
1828 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, | |
1829 Handle<Name> name, | |
1830 int index, | |
1831 PropertyAttributes attributes, | |
1832 Representation representation, | |
1833 TransitionFlag flag) { | |
1834 FieldDescriptor new_field_desc(name, index, attributes, representation); | |
1835 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | |
1836 int unused_property_fields = map->unused_property_fields() - 1; | |
1837 if (unused_property_fields < 0) { | |
1838 unused_property_fields += JSObject::kFieldsAdded; | |
1839 } | |
1840 new_map->set_unused_property_fields(unused_property_fields); | |
1841 return new_map; | |
1842 } | |
1843 | |
1844 | |
1845 void JSObject::AddFastProperty(Handle<JSObject> object, | 1828 void JSObject::AddFastProperty(Handle<JSObject> object, |
1846 Handle<Name> name, | 1829 Handle<Name> name, |
1847 Handle<Object> value, | 1830 Handle<Object> value, |
1848 PropertyAttributes attributes, | 1831 PropertyAttributes attributes, |
1849 StoreFromKeyed store_mode, | 1832 StoreFromKeyed store_mode, |
1850 ValueType value_type, | 1833 ValueType value_type, |
1851 TransitionFlag flag) { | 1834 TransitionFlag flag) { |
1852 ASSERT(!object->IsJSGlobalProxy()); | 1835 ASSERT(!object->IsJSGlobalProxy()); |
1853 ASSERT(DescriptorArray::kNotFound == | 1836 ASSERT(DescriptorArray::kNotFound == |
1854 object->map()->instance_descriptors()->Search( | 1837 object->map()->instance_descriptors()->Search( |
1855 *name, object->map()->NumberOfOwnDescriptors())); | 1838 *name, object->map()->NumberOfOwnDescriptors())); |
1856 | 1839 |
1857 // Normalize the object if the name is an actual name (not the | 1840 // Normalize the object if the name is an actual name (not the |
1858 // hidden strings) and is not a real identifier. | 1841 // hidden strings) and is not a real identifier. |
1859 // Normalize the object if it will have too many fast properties. | 1842 // Normalize the object if it will have too many fast properties. |
1860 Isolate* isolate = object->GetIsolate(); | 1843 Isolate* isolate = object->GetIsolate(); |
1861 if (!name->IsCacheable(isolate) || | 1844 if (!name->IsCacheable(isolate) || |
1862 object->TooManyFastProperties(store_mode)) { | 1845 object->TooManyFastProperties(store_mode)) { |
1863 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 1846 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
1864 AddSlowProperty(object, name, value, attributes); | 1847 AddSlowProperty(object, name, value, attributes); |
1865 return; | 1848 return; |
1866 } | 1849 } |
1867 | 1850 |
1851 // Allocate new instance descriptors with (name, index) added | |
1852 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | |
1853 Representation representation = value->OptimalRepresentation(value_type); | |
1854 | |
1868 // Compute the new index for new field. | 1855 // Compute the new index for new field. |
1869 int index = object->map()->NextFreePropertyIndex(); | 1856 int index = object->map()->NextFreePropertyIndex(); |
1870 | 1857 |
1871 // Allocate new instance descriptors with (name, index) added | 1858 FieldDescriptor new_field_desc(name, index, attributes, representation); |
1872 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | 1859 Handle<Map> new_map = Map::CopyAddDescriptor( |
1873 Representation representation = value->OptimalRepresentation(value_type); | 1860 handle(object->map()), &new_field_desc, flag); |
1874 Handle<Map> new_map = CopyAddFieldDescriptor( | 1861 int unused_property_fields = new_map->unused_property_fields() - 1; |
1875 handle(object->map()), name, index, attributes, representation, flag); | 1862 if (unused_property_fields < 0) { |
1863 unused_property_fields += JSObject::kFieldsAdded; | |
1864 } | |
1865 new_map->set_unused_property_fields(unused_property_fields); | |
1876 | 1866 |
1877 JSObject::MigrateToMap(object, new_map); | 1867 JSObject::MigrateToMap(object, new_map); |
1878 | 1868 |
1879 if (representation.IsDouble()) { | 1869 if (representation.IsDouble()) { |
1880 // Nothing more to be done. | 1870 // Nothing more to be done. |
1881 if (value->IsUninitialized()) return; | 1871 if (value->IsUninitialized()) return; |
1882 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | 1872 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); |
1883 box->set_value(value->Number()); | 1873 box->set_value(value->Number()); |
1884 } else { | 1874 } else { |
1885 object->FastPropertyAtPut(index, *value); | 1875 object->FastPropertyAtPut(index, *value); |
1886 } | 1876 } |
1887 } | 1877 } |
1888 | 1878 |
1889 | 1879 |
1890 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, | |
1891 Handle<Name> name, | |
1892 Handle<Object> value, | |
1893 PropertyAttributes attributes, | |
1894 TransitionFlag flag) { | |
1895 ConstantDescriptor new_constant_desc(name, value, attributes); | |
1896 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | |
1897 } | |
1898 | |
1899 | |
1900 void JSObject::AddConstantProperty(Handle<JSObject> object, | 1880 void JSObject::AddConstantProperty(Handle<JSObject> object, |
1901 Handle<Name> name, | 1881 Handle<Name> name, |
1902 Handle<Object> constant, | 1882 Handle<Object> constant, |
1903 PropertyAttributes attributes, | 1883 PropertyAttributes attributes, |
1904 TransitionFlag initial_flag) { | 1884 TransitionFlag initial_flag) { |
1905 TransitionFlag flag = | 1885 ASSERT(!object->IsGlobalObject()); |
1906 // Do not add transitions to global objects. | 1886 // Don't add transitions to special properties with non-trivial attributes. |
1907 (object->IsGlobalObject() || | 1887 TransitionFlag flag = attributes != NONE ? OMIT_TRANSITION : initial_flag; |
1908 // Don't add transitions to special properties with non-trivial | |
1909 // attributes. | |
1910 attributes != NONE) | |
1911 ? OMIT_TRANSITION | |
1912 : initial_flag; | |
1913 | 1888 |
1914 // Allocate new instance descriptors with (name, constant) added. | 1889 // Allocate new instance descriptors with (name, constant) added. |
1915 Handle<Map> new_map = CopyAddConstantDescriptor( | 1890 ConstantDescriptor new_constant_desc(name, constant, attributes); |
1916 handle(object->map()), name, constant, attributes, flag); | 1891 Handle<Map> new_map = Map::CopyAddDescriptor( |
1892 handle(object->map()), &new_constant_desc, flag); | |
1917 | 1893 |
1918 JSObject::MigrateToMap(object, new_map); | 1894 JSObject::MigrateToMap(object, new_map); |
1919 } | 1895 } |
1920 | 1896 |
1921 | 1897 |
1922 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1898 void JSObject::AddSlowProperty(Handle<JSObject> object, |
1923 Handle<Name> name, | 1899 Handle<Name> name, |
1924 Handle<Object> value, | 1900 Handle<Object> value, |
1925 PropertyAttributes attributes) { | 1901 PropertyAttributes attributes) { |
1926 ASSERT(!object->HasFastProperties()); | 1902 ASSERT(!object->HasFastProperties()); |
(...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4403 return JSProxy::GetElementAttributeWithHandler( | 4379 return JSProxy::GetElementAttributeWithHandler( |
4404 Handle<JSProxy>::cast(proto), receiver, index); | 4380 Handle<JSProxy>::cast(proto), receiver, index); |
4405 } | 4381 } |
4406 if (proto->IsNull()) return ABSENT; | 4382 if (proto->IsNull()) return ABSENT; |
4407 return GetElementAttributeWithReceiver( | 4383 return GetElementAttributeWithReceiver( |
4408 Handle<JSObject>::cast(proto), receiver, index, true); | 4384 Handle<JSObject>::cast(proto), receiver, index, true); |
4409 } | 4385 } |
4410 | 4386 |
4411 | 4387 |
4412 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, | 4388 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, |
4413 Handle<JSObject> obj, | 4389 Handle<Map> fast_map, |
4414 PropertyNormalizationMode mode) { | 4390 PropertyNormalizationMode mode) { |
4415 int index = obj->map()->Hash() % kEntries; | 4391 int index = fast_map->Hash() % kEntries; |
4416 Handle<Object> result = handle(cache->get(index), cache->GetIsolate()); | 4392 Handle<Object> result = handle(cache->get(index), cache->GetIsolate()); |
4417 if (result->IsMap() && | 4393 if (result->IsMap() && |
4418 Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(), | 4394 Handle<Map>::cast(result)->EquivalentToForNormalization( |
4419 mode)) { | 4395 *fast_map, mode)) { |
4420 #ifdef VERIFY_HEAP | 4396 #ifdef VERIFY_HEAP |
4421 if (FLAG_verify_heap) { | 4397 if (FLAG_verify_heap) { |
4422 Handle<Map>::cast(result)->SharedMapVerify(); | 4398 Handle<Map>::cast(result)->SharedMapVerify(); |
4423 } | 4399 } |
4424 #endif | 4400 #endif |
4425 #ifdef ENABLE_SLOW_ASSERTS | 4401 #ifdef ENABLE_SLOW_ASSERTS |
4426 if (FLAG_enable_slow_asserts) { | 4402 if (FLAG_enable_slow_asserts) { |
4427 // The cached map should match newly created normalized map bit-by-bit, | 4403 // The cached map should match newly created normalized map bit-by-bit, |
4428 // except for the code cache, which can contain some ics which can be | 4404 // except for the code cache, which can contain some ics which can be |
4429 // applied to the shared map. | 4405 // applied to the shared map. |
4430 Handle<Map> fresh = Map::CopyNormalized(handle(obj->map()), mode, | 4406 Handle<Map> fresh = Map::CopyNormalized( |
4431 SHARED_NORMALIZED_MAP); | 4407 fast_map, mode, SHARED_NORMALIZED_MAP); |
4432 | 4408 |
4433 ASSERT(memcmp(fresh->address(), | 4409 ASSERT(memcmp(fresh->address(), |
4434 Handle<Map>::cast(result)->address(), | 4410 Handle<Map>::cast(result)->address(), |
4435 Map::kCodeCacheOffset) == 0); | 4411 Map::kCodeCacheOffset) == 0); |
4436 STATIC_ASSERT(Map::kDependentCodeOffset == | 4412 STATIC_ASSERT(Map::kDependentCodeOffset == |
4437 Map::kCodeCacheOffset + kPointerSize); | 4413 Map::kCodeCacheOffset + kPointerSize); |
4438 int offset = Map::kDependentCodeOffset + kPointerSize; | 4414 int offset = Map::kDependentCodeOffset + kPointerSize; |
4439 ASSERT(memcmp(fresh->address() + offset, | 4415 ASSERT(memcmp(fresh->address() + offset, |
4440 Handle<Map>::cast(result)->address() + offset, | 4416 Handle<Map>::cast(result)->address() + offset, |
4441 Map::kSize - offset) == 0); | 4417 Map::kSize - offset) == 0); |
4442 } | 4418 } |
4443 #endif | 4419 #endif |
4444 return Handle<Map>::cast(result); | 4420 return Handle<Map>::cast(result); |
4445 } | 4421 } |
4446 | 4422 |
4447 Isolate* isolate = cache->GetIsolate(); | 4423 Isolate* isolate = cache->GetIsolate(); |
Igor Sheludko
2014/04/14 16:17:53
While we are here: lets get isolate only once in t
| |
4448 Handle<Map> map = Map::CopyNormalized(handle(obj->map()), mode, | 4424 Handle<Map> map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP); |
4449 SHARED_NORMALIZED_MAP); | |
4450 ASSERT(map->is_dictionary_map()); | 4425 ASSERT(map->is_dictionary_map()); |
4451 cache->set(index, *map); | 4426 cache->set(index, *map); |
4452 isolate->counters()->normalized_maps()->Increment(); | 4427 isolate->counters()->normalized_maps()->Increment(); |
4453 | 4428 |
4454 return map; | 4429 return map; |
4455 } | 4430 } |
4456 | 4431 |
4457 | 4432 |
4458 void NormalizedMapCache::Clear() { | 4433 void NormalizedMapCache::Clear() { |
4459 int entries = length(); | 4434 int entries = length(); |
(...skipping 16 matching lines...) Expand all Loading... | |
4476 int expected_additional_properties) { | 4451 int expected_additional_properties) { |
4477 if (!object->HasFastProperties()) return; | 4452 if (!object->HasFastProperties()) return; |
4478 | 4453 |
4479 // The global object is always normalized. | 4454 // The global object is always normalized. |
4480 ASSERT(!object->IsGlobalObject()); | 4455 ASSERT(!object->IsGlobalObject()); |
4481 // JSGlobalProxy must never be normalized | 4456 // JSGlobalProxy must never be normalized |
4482 ASSERT(!object->IsJSGlobalProxy()); | 4457 ASSERT(!object->IsJSGlobalProxy()); |
4483 | 4458 |
4484 Isolate* isolate = object->GetIsolate(); | 4459 Isolate* isolate = object->GetIsolate(); |
4485 HandleScope scope(isolate); | 4460 HandleScope scope(isolate); |
4486 Handle<Map> map(object->map()); | 4461 Handle<Map> map(object->map()); |
Igor Sheludko
2014/04/14 16:17:53
While we are here: map(..., isolate)
| |
4487 | 4462 |
4488 // Allocate new content. | 4463 // Allocate new content. |
4489 int real_size = map->NumberOfOwnDescriptors(); | 4464 int real_size = map->NumberOfOwnDescriptors(); |
4490 int property_count = real_size; | 4465 int property_count = real_size; |
4491 if (expected_additional_properties > 0) { | 4466 if (expected_additional_properties > 0) { |
4492 property_count += expected_additional_properties; | 4467 property_count += expected_additional_properties; |
4493 } else { | 4468 } else { |
4494 property_count += 2; // Make space for two more properties. | 4469 property_count += 2; // Make space for two more properties. |
4495 } | 4470 } |
4496 Handle<NameDictionary> dictionary = | 4471 Handle<NameDictionary> dictionary = |
4497 isolate->factory()->NewNameDictionary(property_count); | 4472 isolate->factory()->NewNameDictionary(property_count); |
4498 | 4473 |
4499 Handle<DescriptorArray> descs(map->instance_descriptors()); | 4474 Handle<DescriptorArray> descs(map->instance_descriptors()); |
Igor Sheludko
2014/04/14 16:17:53
, isolate)
Igor Sheludko
2014/04/14 16:17:53
, isolate)
| |
4500 for (int i = 0; i < real_size; i++) { | 4475 for (int i = 0; i < real_size; i++) { |
4501 PropertyDetails details = descs->GetDetails(i); | 4476 PropertyDetails details = descs->GetDetails(i); |
4502 switch (details.type()) { | 4477 switch (details.type()) { |
4503 case CONSTANT: { | 4478 case CONSTANT: { |
4504 Handle<Name> key(descs->GetKey(i)); | 4479 Handle<Name> key(descs->GetKey(i)); |
Igor Sheludko
2014/04/14 16:17:53
, isolate)
| |
4505 Handle<Object> value(descs->GetConstant(i), isolate); | 4480 Handle<Object> value(descs->GetConstant(i), isolate); |
4506 PropertyDetails d = PropertyDetails( | 4481 PropertyDetails d = PropertyDetails( |
4507 details.attributes(), NORMAL, i + 1); | 4482 details.attributes(), NORMAL, i + 1); |
4508 dictionary = NameDictionaryAdd(dictionary, key, value, d); | 4483 dictionary = NameDictionaryAdd(dictionary, key, value, d); |
4509 break; | 4484 break; |
4510 } | 4485 } |
4511 case FIELD: { | 4486 case FIELD: { |
4512 Handle<Name> key(descs->GetKey(i)); | 4487 Handle<Name> key(descs->GetKey(i)); |
Igor Sheludko
2014/04/14 16:17:53
, isolate)
| |
4513 Handle<Object> value( | 4488 Handle<Object> value( |
4514 object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate); | 4489 object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate); |
4515 PropertyDetails d = | 4490 PropertyDetails d = |
4516 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4491 PropertyDetails(details.attributes(), NORMAL, i + 1); |
4517 dictionary = NameDictionaryAdd(dictionary, key, value, d); | 4492 dictionary = NameDictionaryAdd(dictionary, key, value, d); |
4518 break; | 4493 break; |
4519 } | 4494 } |
4520 case CALLBACKS: { | 4495 case CALLBACKS: { |
4521 Handle<Name> key(descs->GetKey(i)); | 4496 Handle<Name> key(descs->GetKey(i)); |
Igor Sheludko
2014/04/14 16:17:53
, isolate)
| |
4522 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 4497 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
4523 PropertyDetails d = PropertyDetails( | 4498 PropertyDetails d = PropertyDetails( |
4524 details.attributes(), CALLBACKS, i + 1); | 4499 details.attributes(), CALLBACKS, i + 1); |
4525 dictionary = NameDictionaryAdd(dictionary, key, value, d); | 4500 dictionary = NameDictionaryAdd(dictionary, key, value, d); |
4526 break; | 4501 break; |
4527 } | 4502 } |
4528 case INTERCEPTOR: | 4503 case INTERCEPTOR: |
4529 break; | 4504 break; |
4530 case HANDLER: | 4505 case HANDLER: |
4531 case NORMAL: | 4506 case NORMAL: |
4532 case NONEXISTENT: | 4507 case NONEXISTENT: |
4533 UNREACHABLE(); | 4508 UNREACHABLE(); |
4534 break; | 4509 break; |
4535 } | 4510 } |
4536 } | 4511 } |
4537 | 4512 |
4538 // Copy the next enumeration index from instance descriptor. | 4513 // Copy the next enumeration index from instance descriptor. |
4539 dictionary->SetNextEnumerationIndex(real_size + 1); | 4514 dictionary->SetNextEnumerationIndex(real_size + 1); |
4540 | 4515 |
4541 Handle<NormalizedMapCache> cache( | 4516 Handle<NormalizedMapCache> cache( |
4542 isolate->context()->native_context()->normalized_map_cache()); | 4517 isolate->context()->native_context()->normalized_map_cache()); |
Igor Sheludko
2014/04/14 16:17:53
, isolate)
| |
4543 Handle<Map> new_map = NormalizedMapCache::Get(cache, object, mode); | 4518 Handle<Map> new_map = NormalizedMapCache::Get( |
4519 cache, handle(object->map()), mode); | |
Igor Sheludko
2014/04/14 16:17:53
handle(..., isolate)
| |
4544 ASSERT(new_map->is_dictionary_map()); | 4520 ASSERT(new_map->is_dictionary_map()); |
4545 | 4521 |
4546 // From here on we cannot fail and we shouldn't GC anymore. | 4522 // From here on we cannot fail and we shouldn't GC anymore. |
4547 DisallowHeapAllocation no_allocation; | 4523 DisallowHeapAllocation no_allocation; |
4548 | 4524 |
4549 // Resize the object in the heap if necessary. | 4525 // Resize the object in the heap if necessary. |
4550 int new_instance_size = new_map->instance_size(); | 4526 int new_instance_size = new_map->instance_size(); |
4551 int instance_size_delta = map->instance_size() - new_instance_size; | 4527 int instance_size_delta = map->instance_size() - new_instance_size; |
4552 ASSERT(instance_size_delta >= 0); | 4528 ASSERT(instance_size_delta >= 0); |
4553 Heap* heap = isolate->heap(); | 4529 Heap* heap = isolate->heap(); |
(...skipping 11936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16490 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16466 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16491 static const char* error_messages_[] = { | 16467 static const char* error_messages_[] = { |
16492 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16468 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16493 }; | 16469 }; |
16494 #undef ERROR_MESSAGES_TEXTS | 16470 #undef ERROR_MESSAGES_TEXTS |
16495 return error_messages_[reason]; | 16471 return error_messages_[reason]; |
16496 } | 16472 } |
16497 | 16473 |
16498 | 16474 |
16499 } } // namespace v8::internal | 16475 } } // namespace v8::internal |
OLD | NEW |