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

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

Issue 982143002: Revert of Simplify and compact transitions storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
1880 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1915 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1881 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) 1916 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1882 1917
1883 1918
1884 byte Oddball::kind() const { 1919 byte Oddball::kind() const {
1885 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); 1920 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
1886 } 1921 }
1887 1922
1888 1923
1889 void Oddball::set_kind(byte value) { 1924 void Oddball::set_kind(byte value) {
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 if (has_fast_smi_or_object_elements() || 3030 if (has_fast_smi_or_object_elements() ||
2996 has_fast_double_elements()) { 3031 has_fast_double_elements()) {
2997 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 3032 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
2998 return GetHeap()->empty_fixed_array(); 3033 return GetHeap()->empty_fixed_array();
2999 } else if (has_external_array_elements()) { 3034 } else if (has_external_array_elements()) {
3000 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this); 3035 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
3001 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3036 DCHECK(!GetHeap()->InNewSpace(empty_array));
3002 return empty_array; 3037 return empty_array;
3003 } else if (has_fixed_typed_array_elements()) { 3038 } else if (has_fixed_typed_array_elements()) {
3004 FixedTypedArrayBase* empty_array = 3039 FixedTypedArrayBase* empty_array =
3005 GetHeap()->EmptyFixedTypedArrayForMap(this); 3040 GetHeap()->EmptyFixedTypedArrayForMap(this);
3006 DCHECK(!GetHeap()->InNewSpace(empty_array)); 3041 DCHECK(!GetHeap()->InNewSpace(empty_array));
3007 return empty_array; 3042 return empty_array;
3008 } else { 3043 } else {
3009 UNREACHABLE(); 3044 UNREACHABLE();
3010 } 3045 }
3011 return NULL; 3046 return NULL;
3012 } 3047 }
3013 3048
3014 3049
3015 Object** DescriptorArray::GetKeySlot(int descriptor_number) { 3050 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after
5213 } 5248 }
5214 5249
5215 5250
5216 void Map::set_prototype(Object* value, WriteBarrierMode mode) { 5251 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
5217 DCHECK(value->IsNull() || value->IsJSReceiver()); 5252 DCHECK(value->IsNull() || value->IsJSReceiver());
5218 WRITE_FIELD(this, kPrototypeOffset, value); 5253 WRITE_FIELD(this, kPrototypeOffset, value);
5219 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); 5254 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
5220 } 5255 }
5221 5256
5222 5257
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
5223 LayoutDescriptor* Map::layout_descriptor_gc_safe() { 5274 LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5224 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5275 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5225 return LayoutDescriptor::cast_gc_safe(layout_desc); 5276 return LayoutDescriptor::cast_gc_safe(layout_desc);
5226 } 5277 }
5227 5278
5228 5279
5229 bool Map::HasFastPointerLayout() const { 5280 bool Map::HasFastPointerLayout() const {
5230 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); 5281 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5231 return LayoutDescriptor::IsFastPointerLayout(layout_desc); 5282 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5232 } 5283 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
5315 5366
5316 Object* Map::GetBackPointer() { 5367 Object* Map::GetBackPointer() {
5317 Object* object = constructor_or_backpointer(); 5368 Object* object = constructor_or_backpointer();
5318 if (object->IsMap()) { 5369 if (object->IsMap()) {
5319 return object; 5370 return object;
5320 } 5371 }
5321 return GetIsolate()->heap()->undefined_value(); 5372 return GetIsolate()->heap()->undefined_value();
5322 } 5373 }
5323 5374
5324 5375
5325 Map* Map::ElementsTransitionMap() { 5376 bool Map::HasElementsTransition() {
5326 return TransitionArray::SearchSpecial( 5377 return HasTransitionArray() && transitions()->HasElementsTransition();
5327 this, GetHeap()->elements_transition_symbol());
5328 } 5378 }
5329 5379
5330 5380
5331 ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset) 5381 bool Map::HasTransitionArray() const {
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 }
5332 5497
5333 5498
5334 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 5499 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5335 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); 5500 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
5336 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || 5501 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) ||
5337 (value->IsMap() && GetBackPointer()->IsUndefined())); 5502 (value->IsMap() && GetBackPointer()->IsUndefined()));
5338 DCHECK(!value->IsMap() || 5503 DCHECK(!value->IsMap() ||
5339 Map::cast(value)->GetConstructor() == constructor_or_backpointer()); 5504 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5340 set_constructor_or_backpointer(value, mode); 5505 set_constructor_or_backpointer(value, mode);
5341 } 5506 }
5342 5507
5343 5508
5344 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) 5509 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
5345 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) 5510 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
5346 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) 5511 ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5347 ACCESSORS(Map, constructor_or_backpointer, Object, 5512 ACCESSORS(Map, constructor_or_backpointer, Object,
5348 kConstructorOrBackPointerOffset) 5513 kConstructorOrBackPointerOffset)
5349 5514
5350
5351 Object* Map::GetConstructor() const { 5515 Object* Map::GetConstructor() const {
5352 Object* maybe_constructor = constructor_or_backpointer(); 5516 Object* maybe_constructor = constructor_or_backpointer();
5353 // Follow any back pointers. 5517 // Follow any back pointers.
5354 while (maybe_constructor->IsMap()) { 5518 while (maybe_constructor->IsMap()) {
5355 maybe_constructor = 5519 maybe_constructor =
5356 Map::cast(maybe_constructor)->constructor_or_backpointer(); 5520 Map::cast(maybe_constructor)->constructor_or_backpointer();
5357 } 5521 }
5358 return maybe_constructor; 5522 return maybe_constructor;
5359 } 5523 }
5360
5361
5362 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) { 5524 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5363 // Never overwrite a back pointer with a constructor. 5525 // Never overwrite a back pointer with a constructor.
5364 DCHECK(!constructor_or_backpointer()->IsMap()); 5526 DCHECK(!constructor_or_backpointer()->IsMap());
5365 set_constructor_or_backpointer(constructor, mode); 5527 set_constructor_or_backpointer(constructor, mode);
5366 } 5528 }
5367 5529
5368
5369 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) 5530 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
5370 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset) 5531 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
5371 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset) 5532 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
5372 5533
5373 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) 5534 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
5374 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset) 5535 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
5375 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset) 5536 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
5376 5537
5377 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) 5538 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5378 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset) 5539 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
(...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after
7469 #undef READ_SHORT_FIELD 7630 #undef READ_SHORT_FIELD
7470 #undef WRITE_SHORT_FIELD 7631 #undef WRITE_SHORT_FIELD
7471 #undef READ_BYTE_FIELD 7632 #undef READ_BYTE_FIELD
7472 #undef WRITE_BYTE_FIELD 7633 #undef WRITE_BYTE_FIELD
7473 #undef NOBARRIER_READ_BYTE_FIELD 7634 #undef NOBARRIER_READ_BYTE_FIELD
7474 #undef NOBARRIER_WRITE_BYTE_FIELD 7635 #undef NOBARRIER_WRITE_BYTE_FIELD
7475 7636
7476 } } // namespace v8::internal 7637 } } // namespace v8::internal
7477 7638
7478 #endif // V8_OBJECTS_INL_H_ 7639 #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