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-inl.h

Issue 988703002: Revert of Revert of Simplify and compact transitions storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix extra ';', again Created 5 years, 9 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
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 // Review notes: 5 // Review notes:
6 // 6 //
7 // - The use of macros in these inline functions may seem superfluous 7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal 8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep. 9 // code. gcc is not happy when attempting to inline too deep.
10 // 10 //
(...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1873 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1874 } 1874 }
1875 1875
1876 1876
1877 void JSObject::initialize_elements() { 1877 void JSObject::initialize_elements() {
1878 FixedArrayBase* elements = map()->GetInitialElements(); 1878 FixedArrayBase* elements = map()->GetInitialElements();
1879 WRITE_FIELD(this, kElementsOffset, elements); 1879 WRITE_FIELD(this, kElementsOffset, elements);
1880 } 1880 }
1881 1881
1882 1882
1883 Handle<String> Map::ExpectedTransitionKey(Handle<Map> map) {
1884 DisallowHeapAllocation no_gc;
1885 if (!map->HasTransitionArray()) return Handle<String>::null();
1886 TransitionArray* transitions = map->transitions();
1887 if (!transitions->IsSimpleTransition()) return Handle<String>::null();
1888 int transition = TransitionArray::kSimpleTransitionIndex;
1889 PropertyDetails details = transitions->GetTargetDetails(transition);
1890 Name* name = transitions->GetKey(transition);
1891 if (details.type() != DATA) return Handle<String>::null();
1892 if (details.attributes() != NONE) return Handle<String>::null();
1893 if (!name->IsString()) return Handle<String>::null();
1894 return Handle<String>(String::cast(name));
1895 }
1896
1897
1898 Handle<Map> Map::ExpectedTransitionTarget(Handle<Map> map) {
1899 DCHECK(!ExpectedTransitionKey(map).is_null());
1900 return Handle<Map>(map->transitions()->GetTarget(
1901 TransitionArray::kSimpleTransitionIndex));
1902 }
1903
1904
1905 Handle<Map> Map::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
1906 DisallowHeapAllocation no_allocation;
1907 if (!map->HasTransitionArray()) return Handle<Map>::null();
1908 TransitionArray* transitions = map->transitions();
1909 int transition = transitions->Search(kData, *key, NONE);
1910 if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
1911 PropertyDetails details = transitions->GetTargetDetails(transition);
1912 if (details.type() != DATA) return Handle<Map>::null();
1913 DCHECK_EQ(NONE, details.attributes());
1914 return Handle<Map>(transitions->GetTarget(transition));
1915 }
1916
1917
1918 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1883 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1919 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) 1884 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1920 1885
1921 1886
1922 byte Oddball::kind() const { 1887 byte Oddball::kind() const {
1923 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); 1888 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
1924 } 1889 }
1925 1890
1926 1891
1927 void Oddball::set_kind(byte value) { 1892 void Oddball::set_kind(byte value) {
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3091 if (has_fast_smi_or_object_elements() || 3056 if (has_fast_smi_or_object_elements() ||
3092 has_fast_double_elements()) { 3057 has_fast_double_elements()) {
3093 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 3058 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
3094 return GetHeap()->empty_fixed_array(); 3059 return GetHeap()->empty_fixed_array();
3095 } else if (has_external_array_elements()) { 3060 } else if (has_external_array_elements()) {
3096 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this); 3061 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
3097 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3062 DCHECK(!GetHeap()->InNewSpace(empty_array));
3098 return empty_array; 3063 return empty_array;
3099 } else if (has_fixed_typed_array_elements()) { 3064 } else if (has_fixed_typed_array_elements()) {
3100 FixedTypedArrayBase* empty_array = 3065 FixedTypedArrayBase* empty_array =
3101 GetHeap()->EmptyFixedTypedArrayForMap(this); 3066 GetHeap()->EmptyFixedTypedArrayForMap(this);
3102 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3067 DCHECK(!GetHeap()->InNewSpace(empty_array));
3103 return empty_array; 3068 return empty_array;
3104 } else { 3069 } else {
3105 UNREACHABLE(); 3070 UNREACHABLE();
3106 } 3071 }
3107 return NULL; 3072 return NULL;
3108 } 3073 }
3109 3074
3110 3075
3111 Object** DescriptorArray::GetKeySlot(int descriptor_number) { 3076 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after
5310 } 5275 }
5311 5276
5312 5277
5313 void Map::set_prototype(Object* value, WriteBarrierMode mode) { 5278 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
5314 DCHECK(value->IsNull() || value->IsJSReceiver()); 5279 DCHECK(value->IsNull() || value->IsJSReceiver());
5315 WRITE_FIELD(this, kPrototypeOffset, value); 5280 WRITE_FIELD(this, kPrototypeOffset, value);
5316 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); 5281 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
5317 } 5282 }
5318 5283
5319 5284
5320 // If the descriptor is using the empty transition array, install a new empty
5321 // transition array that will have place for an element transition.
5322 static void EnsureHasTransitionArray(Handle<Map> map) {
5323 Handle<TransitionArray> transitions;
5324 if (!map->HasTransitionArray()) {
5325 transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
5326 transitions->set_back_pointer_storage(map->GetBackPointer());
5327 } else if (!map->transitions()->IsFullTransitionArray()) {
5328 transitions = TransitionArray::ExtendToFullTransitionArray(map);
5329 } else {
5330 return;
5331 }
5332 map->set_transitions(*transitions);
5333 }
5334
5335
5336 LayoutDescriptor* Map::layout_descriptor_gc_safe() { 5285 LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5337 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5286 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5338 return LayoutDescriptor::cast_gc_safe(layout_desc); 5287 return LayoutDescriptor::cast_gc_safe(layout_desc);
5339 } 5288 }
5340 5289
5341 5290
5342 bool Map::HasFastPointerLayout() const { 5291 bool Map::HasFastPointerLayout() const {
5343 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5292 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5344 return LayoutDescriptor::IsFastPointerLayout(layout_desc); 5293 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5345 } 5294 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
5428 5377
5429 Object* Map::GetBackPointer() { 5378 Object* Map::GetBackPointer() {
5430 Object* object = constructor_or_backpointer(); 5379 Object* object = constructor_or_backpointer();
5431 if (object->IsMap()) { 5380 if (object->IsMap()) {
5432 return object; 5381 return object;
5433 } 5382 }
5434 return GetIsolate()->heap()->undefined_value(); 5383 return GetIsolate()->heap()->undefined_value();
5435 } 5384 }
5436 5385
5437 5386
5438 bool Map::HasElementsTransition() { 5387 Map* Map::ElementsTransitionMap() {
5439 return HasTransitionArray() && transitions()->HasElementsTransition(); 5388 return TransitionArray::SearchSpecial(
5389 this, GetHeap()->elements_transition_symbol());
5440 } 5390 }
5441 5391
5442 5392
5443 bool Map::HasTransitionArray() const { 5393 ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset)
5444 Object* object = READ_FIELD(this, kTransitionsOffset);
5445 return object->IsTransitionArray();
5446 }
5447
5448
5449 Map* Map::elements_transition_map() {
5450 int index =
5451 transitions()->SearchSpecial(GetHeap()->elements_transition_symbol());
5452 return transitions()->GetTarget(index);
5453 }
5454
5455
5456 bool Map::CanHaveMoreTransitions() {
5457 if (!HasTransitionArray()) return true;
5458 return transitions()->number_of_transitions() <
5459 TransitionArray::kMaxNumberOfTransitions;
5460 }
5461
5462
5463 Map* Map::GetTransition(int transition_index) {
5464 return transitions()->GetTarget(transition_index);
5465 }
5466
5467
5468 int Map::SearchSpecialTransition(Symbol* name) {
5469 if (HasTransitionArray()) {
5470 return transitions()->SearchSpecial(name);
5471 }
5472 return TransitionArray::kNotFound;
5473 }
5474
5475
5476 int Map::SearchTransition(PropertyKind kind, Name* name,
5477 PropertyAttributes attributes) {
5478 if (HasTransitionArray()) {
5479 return transitions()->Search(kind, name, attributes);
5480 }
5481 return TransitionArray::kNotFound;
5482 }
5483
5484
5485 FixedArray* Map::GetPrototypeTransitions() {
5486 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
5487 if (!transitions()->HasPrototypeTransitions()) {
5488 return GetHeap()->empty_fixed_array();
5489 }
5490 return transitions()->GetPrototypeTransitions();
5491 }
5492
5493
5494 void Map::SetPrototypeTransitions(
5495 Handle<Map> map, Handle<FixedArray> proto_transitions) {
5496 EnsureHasTransitionArray(map);
5497 int old_number_of_transitions = map->NumberOfProtoTransitions();
5498 if (Heap::ShouldZapGarbage() && map->HasPrototypeTransitions()) {
5499 DCHECK(map->GetPrototypeTransitions() != *proto_transitions);
5500 map->ZapPrototypeTransitions();
5501 }
5502 map->transitions()->SetPrototypeTransitions(*proto_transitions);
5503 map->SetNumberOfProtoTransitions(old_number_of_transitions);
5504 }
5505
5506
5507 bool Map::HasPrototypeTransitions() {
5508 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
5509 }
5510
5511
5512 TransitionArray* Map::transitions() const {
5513 DCHECK(HasTransitionArray());
5514 Object* object = READ_FIELD(this, kTransitionsOffset);
5515 return TransitionArray::cast(object);
5516 }
5517
5518
5519 void Map::set_transitions(TransitionArray* transition_array,
5520 WriteBarrierMode mode) {
5521 // Transition arrays are not shared. When one is replaced, it should not
5522 // keep referenced objects alive, so we zap it.
5523 // When there is another reference to the array somewhere (e.g. a handle),
5524 // not zapping turns from a waste of memory into a source of crashes.
5525 if (HasTransitionArray()) {
5526 #ifdef DEBUG
5527 for (int i = 0; i < transitions()->number_of_transitions(); i++) {
5528 Map* target = transitions()->GetTarget(i);
5529 if (target->instance_descriptors() == instance_descriptors()) {
5530 Name* key = transitions()->GetKey(i);
5531 int new_target_index;
5532 if (TransitionArray::IsSpecialTransition(key)) {
5533 new_target_index = transition_array->SearchSpecial(Symbol::cast(key));
5534 } else {
5535 PropertyDetails details =
5536 TransitionArray::GetTargetDetails(key, target);
5537 new_target_index = transition_array->Search(details.kind(), key,
5538 details.attributes());
5539 }
5540 DCHECK_NE(TransitionArray::kNotFound, new_target_index);
5541 DCHECK_EQ(target, transition_array->GetTarget(new_target_index));
5542 }
5543 }
5544 #endif
5545 DCHECK(transitions() != transition_array);
5546 ZapTransitions();
5547 }
5548
5549 WRITE_FIELD(this, kTransitionsOffset, transition_array);
5550 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTransitionsOffset,
5551 transition_array, mode);
5552 }
5553
5554
5555 void Map::init_transitions(Object* undefined) {
5556 DCHECK(undefined->IsUndefined());
5557 WRITE_FIELD(this, kTransitionsOffset, undefined);
5558 }
5559 5394
5560 5395
5561 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 5396 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5562 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); 5397 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
5563 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || 5398 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) ||
5564 (value->IsMap() && GetBackPointer()->IsUndefined())); 5399 (value->IsMap() && GetBackPointer()->IsUndefined()));
5565 DCHECK(!value->IsMap() || 5400 DCHECK(!value->IsMap() ||
5566 Map::cast(value)->GetConstructor() == constructor_or_backpointer()); 5401 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5567 set_constructor_or_backpointer(value, mode); 5402 set_constructor_or_backpointer(value, mode);
5568 } 5403 }
5569 5404
5570 5405
5571 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) 5406 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
5572 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) 5407 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
5573 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) 5408 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5574 ACCESSORS(Map, constructor_or_backpointer, Object, 5409 ACCESSORS(Map, constructor_or_backpointer, Object,
5575 kConstructorOrBackPointerOffset) 5410 kConstructorOrBackPointerOffset)
5576 5411
5412
5577 Object* Map::GetConstructor() const { 5413 Object* Map::GetConstructor() const {
5578 Object* maybe_constructor = constructor_or_backpointer(); 5414 Object* maybe_constructor = constructor_or_backpointer();
5579 // Follow any back pointers. 5415 // Follow any back pointers.
5580 while (maybe_constructor->IsMap()) { 5416 while (maybe_constructor->IsMap()) {
5581 maybe_constructor = 5417 maybe_constructor =
5582 Map::cast(maybe_constructor)->constructor_or_backpointer(); 5418 Map::cast(maybe_constructor)->constructor_or_backpointer();
5583 } 5419 }
5584 return maybe_constructor; 5420 return maybe_constructor;
5585 } 5421 }
5422
5423
5586 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) { 5424 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5587 // Never overwrite a back pointer with a constructor. 5425 // Never overwrite a back pointer with a constructor.
5588 DCHECK(!constructor_or_backpointer()->IsMap()); 5426 DCHECK(!constructor_or_backpointer()->IsMap());
5589 set_constructor_or_backpointer(constructor, mode); 5427 set_constructor_or_backpointer(constructor, mode);
5590 } 5428 }
5591 5429
5430
5592 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) 5431 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
5593 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset) 5432 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
5594 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset) 5433 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
5595 5434
5596 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) 5435 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
5597 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset) 5436 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
5598 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset) 5437 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
5599 5438
5600 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) 5439 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5601 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset) 5440 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
(...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after
7692 #undef READ_SHORT_FIELD 7531 #undef READ_SHORT_FIELD
7693 #undef WRITE_SHORT_FIELD 7532 #undef WRITE_SHORT_FIELD
7694 #undef READ_BYTE_FIELD 7533 #undef READ_BYTE_FIELD
7695 #undef WRITE_BYTE_FIELD 7534 #undef WRITE_BYTE_FIELD
7696 #undef NOBARRIER_READ_BYTE_FIELD 7535 #undef NOBARRIER_READ_BYTE_FIELD
7697 #undef NOBARRIER_WRITE_BYTE_FIELD 7536 #undef NOBARRIER_WRITE_BYTE_FIELD
7698 7537
7699 } } // namespace v8::internal 7538 } } // namespace v8::internal
7700 7539
7701 #endif // V8_OBJECTS_INL_H_ 7540 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698