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

Side by Side Diff: src/objects.cc

Issue 237143004: Initial steps for moving code onto Map (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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') | no next file » | 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 // 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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698