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

Side by Side Diff: src/objects-inl.h

Issue 980573002: Simplify and compact transitions storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix -Werror=pedantic ( rebase 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 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1870 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1871 } 1871 }
1872 1872
1873 1873
1874 void JSObject::initialize_elements() { 1874 void JSObject::initialize_elements() {
1875 FixedArrayBase* elements = map()->GetInitialElements(); 1875 FixedArrayBase* elements = map()->GetInitialElements();
1876 WRITE_FIELD(this, kElementsOffset, elements); 1876 WRITE_FIELD(this, kElementsOffset, elements);
1877 } 1877 }
1878 1878
1879 1879
1880 Handle<String> Map::ExpectedTransitionKey(Handle<Map> map) {
1881 DisallowHeapAllocation no_gc;
1882 if (!map->HasTransitionArray()) return Handle<String>::null();
1883 TransitionArray* transitions = map->transitions();
1884 if (!transitions->IsSimpleTransition()) return Handle<String>::null();
1885 int transition = TransitionArray::kSimpleTransitionIndex;
1886 PropertyDetails details = transitions->GetTargetDetails(transition);
1887 Name* name = transitions->GetKey(transition);
1888 if (details.type() != DATA) return Handle<String>::null();
1889 if (details.attributes() != NONE) return Handle<String>::null();
1890 if (!name->IsString()) return Handle<String>::null();
1891 return Handle<String>(String::cast(name));
1892 }
1893
1894
1895 Handle<Map> Map::ExpectedTransitionTarget(Handle<Map> map) {
1896 DCHECK(!ExpectedTransitionKey(map).is_null());
1897 return Handle<Map>(map->transitions()->GetTarget(
1898 TransitionArray::kSimpleTransitionIndex));
1899 }
1900
1901
1902 Handle<Map> Map::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
1903 DisallowHeapAllocation no_allocation;
1904 if (!map->HasTransitionArray()) return Handle<Map>::null();
1905 TransitionArray* transitions = map->transitions();
1906 int transition = transitions->Search(kData, *key, NONE);
1907 if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
1908 PropertyDetails details = transitions->GetTargetDetails(transition);
1909 if (details.type() != DATA) return Handle<Map>::null();
1910 DCHECK_EQ(NONE, details.attributes());
1911 return Handle<Map>(transitions->GetTarget(transition));
1912 }
1913
1914
1915 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1880 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1916 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) 1881 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1917 1882
1918 1883
1919 byte Oddball::kind() const { 1884 byte Oddball::kind() const {
1920 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); 1885 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
1921 } 1886 }
1922 1887
1923 1888
1924 void Oddball::set_kind(byte value) { 1889 void Oddball::set_kind(byte value) {
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
3030 if (has_fast_smi_or_object_elements() || 2995 if (has_fast_smi_or_object_elements() ||
3031 has_fast_double_elements()) { 2996 has_fast_double_elements()) {
3032 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 2997 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
3033 return GetHeap()->empty_fixed_array(); 2998 return GetHeap()->empty_fixed_array();
3034 } else if (has_external_array_elements()) { 2999 } else if (has_external_array_elements()) {
3035 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this); 3000 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
3036 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3001 DCHECK(!GetHeap()->InNewSpace(empty_array));
3037 return empty_array; 3002 return empty_array;
3038 } else if (has_fixed_typed_array_elements()) { 3003 } else if (has_fixed_typed_array_elements()) {
3039 FixedTypedArrayBase* empty_array = 3004 FixedTypedArrayBase* empty_array =
3040 GetHeap()->EmptyFixedTypedArrayForMap(this); 3005 GetHeap()->EmptyFixedTypedArrayForMap(this);
3041 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3006 DCHECK(!GetHeap()->InNewSpace(empty_array));
3042 return empty_array; 3007 return empty_array;
3043 } else { 3008 } else {
3044 UNREACHABLE(); 3009 UNREACHABLE();
3045 } 3010 }
3046 return NULL; 3011 return NULL;
3047 } 3012 }
3048 3013
3049 3014
3050 Object** DescriptorArray::GetKeySlot(int descriptor_number) { 3015 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after
5248 } 5213 }
5249 5214
5250 5215
5251 void Map::set_prototype(Object* value, WriteBarrierMode mode) { 5216 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
5252 DCHECK(value->IsNull() || value->IsJSReceiver()); 5217 DCHECK(value->IsNull() || value->IsJSReceiver());
5253 WRITE_FIELD(this, kPrototypeOffset, value); 5218 WRITE_FIELD(this, kPrototypeOffset, value);
5254 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); 5219 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
5255 } 5220 }
5256 5221
5257 5222
5258 // If the descriptor is using the empty transition array, install a new empty
5259 // transition array that will have place for an element transition.
5260 static void EnsureHasTransitionArray(Handle<Map> map) {
5261 Handle<TransitionArray> transitions;
5262 if (!map->HasTransitionArray()) {
5263 transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
5264 transitions->set_back_pointer_storage(map->GetBackPointer());
5265 } else if (!map->transitions()->IsFullTransitionArray()) {
5266 transitions = TransitionArray::ExtendToFullTransitionArray(map);
5267 } else {
5268 return;
5269 }
5270 map->set_transitions(*transitions);
5271 }
5272
5273
5274 LayoutDescriptor* Map::layout_descriptor_gc_safe() { 5223 LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5275 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5224 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5276 return LayoutDescriptor::cast_gc_safe(layout_desc); 5225 return LayoutDescriptor::cast_gc_safe(layout_desc);
5277 } 5226 }
5278 5227
5279 5228
5280 bool Map::HasFastPointerLayout() const { 5229 bool Map::HasFastPointerLayout() const {
5281 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5230 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5282 return LayoutDescriptor::IsFastPointerLayout(layout_desc); 5231 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5283 } 5232 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
5366 5315
5367 Object* Map::GetBackPointer() { 5316 Object* Map::GetBackPointer() {
5368 Object* object = constructor_or_backpointer(); 5317 Object* object = constructor_or_backpointer();
5369 if (object->IsMap()) { 5318 if (object->IsMap()) {
5370 return object; 5319 return object;
5371 } 5320 }
5372 return GetIsolate()->heap()->undefined_value(); 5321 return GetIsolate()->heap()->undefined_value();
5373 } 5322 }
5374 5323
5375 5324
5376 bool Map::HasElementsTransition() { 5325 Map* Map::ElementsTransitionMap() {
5377 return HasTransitionArray() && transitions()->HasElementsTransition(); 5326 return TransitionArray::SearchSpecial(
5327 this, GetHeap()->elements_transition_symbol());
5378 } 5328 }
5379 5329
5380 5330
5381 bool Map::HasTransitionArray() const { 5331 ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset)
5382 Object* object = READ_FIELD(this, kTransitionsOffset);
5383 return object->IsTransitionArray();
5384 }
5385
5386
5387 Map* Map::elements_transition_map() {
5388 int index =
5389 transitions()->SearchSpecial(GetHeap()->elements_transition_symbol());
5390 return transitions()->GetTarget(index);
5391 }
5392
5393
5394 bool Map::CanHaveMoreTransitions() {
5395 if (!HasTransitionArray()) return true;
5396 return transitions()->number_of_transitions() <
5397 TransitionArray::kMaxNumberOfTransitions;
5398 }
5399
5400
5401 Map* Map::GetTransition(int transition_index) {
5402 return transitions()->GetTarget(transition_index);
5403 }
5404
5405
5406 int Map::SearchSpecialTransition(Symbol* name) {
5407 if (HasTransitionArray()) {
5408 return transitions()->SearchSpecial(name);
5409 }
5410 return TransitionArray::kNotFound;
5411 }
5412
5413
5414 int Map::SearchTransition(PropertyKind kind, Name* name,
5415 PropertyAttributes attributes) {
5416 if (HasTransitionArray()) {
5417 return transitions()->Search(kind, name, attributes);
5418 }
5419 return TransitionArray::kNotFound;
5420 }
5421
5422
5423 FixedArray* Map::GetPrototypeTransitions() {
5424 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
5425 if (!transitions()->HasPrototypeTransitions()) {
5426 return GetHeap()->empty_fixed_array();
5427 }
5428 return transitions()->GetPrototypeTransitions();
5429 }
5430
5431
5432 void Map::SetPrototypeTransitions(
5433 Handle<Map> map, Handle<FixedArray> proto_transitions) {
5434 EnsureHasTransitionArray(map);
5435 int old_number_of_transitions = map->NumberOfProtoTransitions();
5436 if (Heap::ShouldZapGarbage() && map->HasPrototypeTransitions()) {
5437 DCHECK(map->GetPrototypeTransitions() != *proto_transitions);
5438 map->ZapPrototypeTransitions();
5439 }
5440 map->transitions()->SetPrototypeTransitions(*proto_transitions);
5441 map->SetNumberOfProtoTransitions(old_number_of_transitions);
5442 }
5443
5444
5445 bool Map::HasPrototypeTransitions() {
5446 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
5447 }
5448
5449
5450 TransitionArray* Map::transitions() const {
5451 DCHECK(HasTransitionArray());
5452 Object* object = READ_FIELD(this, kTransitionsOffset);
5453 return TransitionArray::cast(object);
5454 }
5455
5456
5457 void Map::set_transitions(TransitionArray* transition_array,
5458 WriteBarrierMode mode) {
5459 // Transition arrays are not shared. When one is replaced, it should not
5460 // keep referenced objects alive, so we zap it.
5461 // When there is another reference to the array somewhere (e.g. a handle),
5462 // not zapping turns from a waste of memory into a source of crashes.
5463 if (HasTransitionArray()) {
5464 #ifdef DEBUG
5465 for (int i = 0; i < transitions()->number_of_transitions(); i++) {
5466 Map* target = transitions()->GetTarget(i);
5467 if (target->instance_descriptors() == instance_descriptors()) {
5468 Name* key = transitions()->GetKey(i);
5469 int new_target_index;
5470 if (TransitionArray::IsSpecialTransition(key)) {
5471 new_target_index = transition_array->SearchSpecial(Symbol::cast(key));
5472 } else {
5473 PropertyDetails details =
5474 TransitionArray::GetTargetDetails(key, target);
5475 new_target_index = transition_array->Search(details.kind(), key,
5476 details.attributes());
5477 }
5478 DCHECK_NE(TransitionArray::kNotFound, new_target_index);
5479 DCHECK_EQ(target, transition_array->GetTarget(new_target_index));
5480 }
5481 }
5482 #endif
5483 DCHECK(transitions() != transition_array);
5484 ZapTransitions();
5485 }
5486
5487 WRITE_FIELD(this, kTransitionsOffset, transition_array);
5488 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTransitionsOffset,
5489 transition_array, mode);
5490 }
5491
5492
5493 void Map::init_transitions(Object* undefined) {
5494 DCHECK(undefined->IsUndefined());
5495 WRITE_FIELD(this, kTransitionsOffset, undefined);
5496 }
5497 5332
5498 5333
5499 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 5334 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5500 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); 5335 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
5501 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || 5336 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) ||
5502 (value->IsMap() && GetBackPointer()->IsUndefined())); 5337 (value->IsMap() && GetBackPointer()->IsUndefined()));
5503 DCHECK(!value->IsMap() || 5338 DCHECK(!value->IsMap() ||
5504 Map::cast(value)->GetConstructor() == constructor_or_backpointer()); 5339 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5505 set_constructor_or_backpointer(value, mode); 5340 set_constructor_or_backpointer(value, mode);
5506 } 5341 }
5507 5342
5508 5343
5509 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) 5344 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
5510 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) 5345 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
5511 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) 5346 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5512 ACCESSORS(Map, constructor_or_backpointer, Object, 5347 ACCESSORS(Map, constructor_or_backpointer, Object,
5513 kConstructorOrBackPointerOffset) 5348 kConstructorOrBackPointerOffset)
5514 5349
5350
5515 Object* Map::GetConstructor() const { 5351 Object* Map::GetConstructor() const {
5516 Object* maybe_constructor = constructor_or_backpointer(); 5352 Object* maybe_constructor = constructor_or_backpointer();
5517 // Follow any back pointers. 5353 // Follow any back pointers.
5518 while (maybe_constructor->IsMap()) { 5354 while (maybe_constructor->IsMap()) {
5519 maybe_constructor = 5355 maybe_constructor =
5520 Map::cast(maybe_constructor)->constructor_or_backpointer(); 5356 Map::cast(maybe_constructor)->constructor_or_backpointer();
5521 } 5357 }
5522 return maybe_constructor; 5358 return maybe_constructor;
5523 } 5359 }
5360
5361
5524 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) { 5362 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5525 // Never overwrite a back pointer with a constructor. 5363 // Never overwrite a back pointer with a constructor.
5526 DCHECK(!constructor_or_backpointer()->IsMap()); 5364 DCHECK(!constructor_or_backpointer()->IsMap());
5527 set_constructor_or_backpointer(constructor, mode); 5365 set_constructor_or_backpointer(constructor, mode);
5528 } 5366 }
5529 5367
5368
5530 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) 5369 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
5531 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset) 5370 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
5532 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset) 5371 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
5533 5372
5534 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) 5373 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
5535 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset) 5374 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
5536 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset) 5375 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
5537 5376
5538 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) 5377 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5539 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset) 5378 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
(...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after
7630 #undef READ_SHORT_FIELD 7469 #undef READ_SHORT_FIELD
7631 #undef WRITE_SHORT_FIELD 7470 #undef WRITE_SHORT_FIELD
7632 #undef READ_BYTE_FIELD 7471 #undef READ_BYTE_FIELD
7633 #undef WRITE_BYTE_FIELD 7472 #undef WRITE_BYTE_FIELD
7634 #undef NOBARRIER_READ_BYTE_FIELD 7473 #undef NOBARRIER_READ_BYTE_FIELD
7635 #undef NOBARRIER_WRITE_BYTE_FIELD 7474 #undef NOBARRIER_WRITE_BYTE_FIELD
7636 7475
7637 } } // namespace v8::internal 7476 } } // namespace v8::internal
7638 7477
7639 #endif // V8_OBJECTS_INL_H_ 7478 #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