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

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

Issue 950283002: Move Maps' back pointers from "transitions" to "constructor" field (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix stupidity on arm64 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.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 5342 matching lines...) Expand 10 before | Expand all | Expand 10 after
5353 // This function does not support appending double field descriptors and 5353 // This function does not support appending double field descriptors and
5354 // it should never try to (otherwise, layout descriptor must be updated too). 5354 // it should never try to (otherwise, layout descriptor must be updated too).
5355 #ifdef DEBUG 5355 #ifdef DEBUG
5356 PropertyDetails details = desc->GetDetails(); 5356 PropertyDetails details = desc->GetDetails();
5357 CHECK(details.type() != DATA || !details.representation().IsDouble()); 5357 CHECK(details.type() != DATA || !details.representation().IsDouble());
5358 #endif 5358 #endif
5359 } 5359 }
5360 5360
5361 5361
5362 Object* Map::GetBackPointer() { 5362 Object* Map::GetBackPointer() {
5363 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 5363 Object* object = constructor_or_backpointer();
5364 if (object->IsTransitionArray()) { 5364 if (object->IsMap()) {
5365 return TransitionArray::cast(object)->back_pointer_storage();
5366 } else {
5367 DCHECK(object->IsMap() || object->IsUndefined());
5368 return object; 5365 return object;
5369 } 5366 }
5367 return GetIsolate()->heap()->undefined_value();
5370 } 5368 }
5371 5369
5372 5370
5373 bool Map::HasElementsTransition() { 5371 bool Map::HasElementsTransition() {
5374 return HasTransitionArray() && transitions()->HasElementsTransition(); 5372 return HasTransitionArray() && transitions()->HasElementsTransition();
5375 } 5373 }
5376 5374
5377 5375
5378 bool Map::HasTransitionArray() const { 5376 bool Map::HasTransitionArray() const {
5379 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 5377 Object* object = READ_FIELD(this, kTransitionsOffset);
5380 return object->IsTransitionArray(); 5378 return object->IsTransitionArray();
5381 } 5379 }
5382 5380
5383 5381
5384 Map* Map::elements_transition_map() { 5382 Map* Map::elements_transition_map() {
5385 int index = 5383 int index =
5386 transitions()->SearchSpecial(GetHeap()->elements_transition_symbol()); 5384 transitions()->SearchSpecial(GetHeap()->elements_transition_symbol());
5387 return transitions()->GetTarget(index); 5385 return transitions()->GetTarget(index);
5388 } 5386 }
5389 5387
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5439 } 5437 }
5440 5438
5441 5439
5442 bool Map::HasPrototypeTransitions() { 5440 bool Map::HasPrototypeTransitions() {
5443 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); 5441 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
5444 } 5442 }
5445 5443
5446 5444
5447 TransitionArray* Map::transitions() const { 5445 TransitionArray* Map::transitions() const {
5448 DCHECK(HasTransitionArray()); 5446 DCHECK(HasTransitionArray());
5449 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 5447 Object* object = READ_FIELD(this, kTransitionsOffset);
5450 return TransitionArray::cast(object); 5448 return TransitionArray::cast(object);
5451 } 5449 }
5452 5450
5453 5451
5454 void Map::set_transitions(TransitionArray* transition_array, 5452 void Map::set_transitions(TransitionArray* transition_array,
5455 WriteBarrierMode mode) { 5453 WriteBarrierMode mode) {
5456 // Transition arrays are not shared. When one is replaced, it should not 5454 // Transition arrays are not shared. When one is replaced, it should not
5457 // keep referenced objects alive, so we zap it. 5455 // keep referenced objects alive, so we zap it.
5458 // When there is another reference to the array somewhere (e.g. a handle), 5456 // When there is another reference to the array somewhere (e.g. a handle),
5459 // not zapping turns from a waste of memory into a source of crashes. 5457 // not zapping turns from a waste of memory into a source of crashes.
(...skipping 14 matching lines...) Expand all
5474 } 5472 }
5475 DCHECK_NE(TransitionArray::kNotFound, new_target_index); 5473 DCHECK_NE(TransitionArray::kNotFound, new_target_index);
5476 DCHECK_EQ(target, transition_array->GetTarget(new_target_index)); 5474 DCHECK_EQ(target, transition_array->GetTarget(new_target_index));
5477 } 5475 }
5478 } 5476 }
5479 #endif 5477 #endif
5480 DCHECK(transitions() != transition_array); 5478 DCHECK(transitions() != transition_array);
5481 ZapTransitions(); 5479 ZapTransitions();
5482 } 5480 }
5483 5481
5484 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); 5482 WRITE_FIELD(this, kTransitionsOffset, transition_array);
5485 CONDITIONAL_WRITE_BARRIER( 5483 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTransitionsOffset,
5486 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); 5484 transition_array, mode);
5487 } 5485 }
5488 5486
5489 5487
5490 void Map::init_back_pointer(Object* undefined) { 5488 void Map::init_transitions(Object* undefined) {
5491 DCHECK(undefined->IsUndefined()); 5489 DCHECK(undefined->IsUndefined());
5492 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined); 5490 WRITE_FIELD(this, kTransitionsOffset, undefined);
5493 } 5491 }
5494 5492
5495 5493
5496 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 5494 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5497 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); 5495 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
5498 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || 5496 DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) ||
5499 (value->IsMap() && GetBackPointer()->IsUndefined())); 5497 (value->IsMap() && GetBackPointer()->IsUndefined()));
5500 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 5498 DCHECK(!value->IsMap() ||
5501 if (object->IsTransitionArray()) { 5499 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5502 TransitionArray::cast(object)->set_back_pointer_storage(value); 5500 set_constructor_or_backpointer(value, mode);
5503 } else {
5504 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
5505 CONDITIONAL_WRITE_BARRIER(
5506 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
5507 }
5508 } 5501 }
5509 5502
5510 5503
5511 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) 5504 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
5512 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) 5505 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
5513 ACCESSORS(Map, constructor, Object, kConstructorOffset) 5506 ACCESSORS(Map, constructor_or_backpointer, Object,
5507 kConstructorOrBackPointerOffset)
5508
5509 Object* Map::GetConstructor() const {
5510 Object* maybe_constructor = constructor_or_backpointer();
5511 // Follow any back pointers.
5512 while (maybe_constructor->IsMap()) {
5513 maybe_constructor =
5514 Map::cast(maybe_constructor)->constructor_or_backpointer();
5515 }
5516 return maybe_constructor;
5517 }
5518 void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5519 // Never overwrite a back pointer with a constructor.
5520 DCHECK(!constructor_or_backpointer()->IsMap());
5521 set_constructor_or_backpointer(constructor, mode);
5522 }
5514 5523
5515 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) 5524 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
5516 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset) 5525 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
5517 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset) 5526 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
5518 5527
5519 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset) 5528 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
5520 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset) 5529 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
5521 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset) 5530 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
5522 5531
5523 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) 5532 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
6192 // When there is no initial map and the prototype is a JSObject, the 6201 // When there is no initial map and the prototype is a JSObject, the
6193 // initial map field is used for the prototype field. 6202 // initial map field is used for the prototype field.
6194 return prototype_or_initial_map(); 6203 return prototype_or_initial_map();
6195 } 6204 }
6196 6205
6197 6206
6198 Object* JSFunction::prototype() { 6207 Object* JSFunction::prototype() {
6199 DCHECK(has_prototype()); 6208 DCHECK(has_prototype());
6200 // If the function's prototype property has been set to a non-JSObject 6209 // If the function's prototype property has been set to a non-JSObject
6201 // value, that value is stored in the constructor field of the map. 6210 // value, that value is stored in the constructor field of the map.
6202 if (map()->has_non_instance_prototype()) return map()->constructor(); 6211 if (map()->has_non_instance_prototype()) {
6212 Object* prototype = map()->GetConstructor();
6213 // The map must have a prototype in that field, not a back pointer.
6214 DCHECK(!prototype->IsMap());
6215 return prototype;
6216 }
6203 return instance_prototype(); 6217 return instance_prototype();
6204 } 6218 }
6205 6219
6206 6220
6207 bool JSFunction::should_have_prototype() { 6221 bool JSFunction::should_have_prototype() {
6208 return map()->function_with_prototype(); 6222 return map()->function_with_prototype();
6209 } 6223 }
6210 6224
6211 6225
6212 bool JSFunction::is_compiled() { 6226 bool JSFunction::is_compiled() {
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after
7615 #undef READ_SHORT_FIELD 7629 #undef READ_SHORT_FIELD
7616 #undef WRITE_SHORT_FIELD 7630 #undef WRITE_SHORT_FIELD
7617 #undef READ_BYTE_FIELD 7631 #undef READ_BYTE_FIELD
7618 #undef WRITE_BYTE_FIELD 7632 #undef WRITE_BYTE_FIELD
7619 #undef NOBARRIER_READ_BYTE_FIELD 7633 #undef NOBARRIER_READ_BYTE_FIELD
7620 #undef NOBARRIER_WRITE_BYTE_FIELD 7634 #undef NOBARRIER_WRITE_BYTE_FIELD
7621 7635
7622 } } // namespace v8::internal 7636 } } // namespace v8::internal
7623 7637
7624 #endif // V8_OBJECTS_INL_H_ 7638 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698