[csa] Add TNode<MaybeObject>.
LoadMaybeWeakField returns a TNode<MaybeObject>, and the only way to extract values from it is through explicit functions. BUG=v8:7308 Change-Id: I98da6b715527bb9976b4c78ed9caaa39fbcb3ed5 Reviewed-on: https://chromium-review.googlesource.com/1014106 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#52732}
This commit is contained in:
parent
5c9b30ae38
commit
c823ca959e
@ -829,6 +829,12 @@ TNode<BoolT> CodeStubAssembler::TaggedIsSmi(SloppyTNode<Object> a) {
|
||||
IntPtrConstant(0));
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::TaggedIsSmi(TNode<MaybeObject> a) {
|
||||
return WordEqual(
|
||||
WordAnd(BitcastMaybeObjectToWord(a), IntPtrConstant(kSmiTagMask)),
|
||||
IntPtrConstant(0));
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::TaggedIsNotSmi(SloppyTNode<Object> a) {
|
||||
return WordNotEqual(
|
||||
WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)),
|
||||
@ -1492,15 +1498,15 @@ TNode<PrototypeInfo> CodeStubAssembler::LoadMapPrototypeInfo(
|
||||
SloppyTNode<Map> map, Label* if_no_proto_info) {
|
||||
Label if_strong_heap_object(this);
|
||||
CSA_ASSERT(this, IsMap(map));
|
||||
Node* maybe_prototype_info =
|
||||
LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
|
||||
VARIABLE(prototype_info, MachineRepresentation::kTagged);
|
||||
TNode<MaybeObject> maybe_prototype_info =
|
||||
LoadMaybeWeakObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
|
||||
TVARIABLE(Object, prototype_info);
|
||||
DispatchMaybeObject(maybe_prototype_info, if_no_proto_info, if_no_proto_info,
|
||||
if_no_proto_info, &if_strong_heap_object,
|
||||
&prototype_info);
|
||||
|
||||
BIND(&if_strong_heap_object);
|
||||
GotoIfNot(WordEqual(LoadMap(prototype_info.value()),
|
||||
GotoIfNot(WordEqual(LoadMap(CAST(prototype_info.value())),
|
||||
LoadRoot(Heap::kPrototypeInfoMapRootIndex)),
|
||||
if_no_proto_info);
|
||||
return CAST(prototype_info.value());
|
||||
@ -1681,49 +1687,62 @@ TNode<Object> CodeStubAssembler::LoadWeakCellValue(
|
||||
return value;
|
||||
}
|
||||
|
||||
void CodeStubAssembler::DispatchMaybeObject(Node* maybe_object, Label* if_smi,
|
||||
Label* if_cleared, Label* if_weak,
|
||||
Label* if_strong,
|
||||
Variable* extracted) {
|
||||
void CodeStubAssembler::DispatchMaybeObject(TNode<MaybeObject> maybe_object,
|
||||
Label* if_smi, Label* if_cleared,
|
||||
Label* if_weak, Label* if_strong,
|
||||
TVariable<Object>* extracted) {
|
||||
Label inner_if_smi(this), inner_if_strong(this);
|
||||
|
||||
GotoIf(TaggedIsSmi(maybe_object), &inner_if_smi);
|
||||
|
||||
GotoIf(WordEqual(maybe_object, IntPtrConstant(reinterpret_cast<intptr_t>(
|
||||
HeapObjectReference::ClearedValue()))),
|
||||
GotoIf(WordEqual(BitcastMaybeObjectToWord(maybe_object),
|
||||
IntPtrConstant(reinterpret_cast<intptr_t>(
|
||||
HeapObjectReference::ClearedValue()))),
|
||||
if_cleared);
|
||||
|
||||
GotoIf(WordEqual(WordAnd(BitcastTaggedToWord(maybe_object),
|
||||
GotoIf(WordEqual(WordAnd(BitcastMaybeObjectToWord(maybe_object),
|
||||
IntPtrConstant(kWeakHeapObjectMask)),
|
||||
IntPtrConstant(0)),
|
||||
&inner_if_strong);
|
||||
|
||||
extracted->Bind(
|
||||
BitcastWordToTagged(WordAnd(BitcastTaggedToWord(maybe_object),
|
||||
IntPtrConstant(~kWeakHeapObjectMask))));
|
||||
*extracted =
|
||||
BitcastWordToTagged(WordAnd(BitcastMaybeObjectToWord(maybe_object),
|
||||
IntPtrConstant(~kWeakHeapObjectMask)));
|
||||
Goto(if_weak);
|
||||
|
||||
BIND(&inner_if_smi);
|
||||
extracted->Bind(maybe_object);
|
||||
*extracted = ToStrongHeapObjectOrSmi(maybe_object);
|
||||
Goto(if_smi);
|
||||
|
||||
BIND(&inner_if_strong);
|
||||
extracted->Bind(maybe_object);
|
||||
*extracted = ToStrongHeapObject(maybe_object);
|
||||
Goto(if_strong);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsStrongHeapObject(Node* value) {
|
||||
return WordEqual(
|
||||
WordAnd(BitcastTaggedToWord(value), IntPtrConstant(kWeakHeapObjectMask)),
|
||||
IntPtrConstant(0));
|
||||
TNode<BoolT> CodeStubAssembler::IsStrongHeapObject(TNode<MaybeObject> value) {
|
||||
return WordEqual(WordAnd(BitcastMaybeObjectToWord(value),
|
||||
IntPtrConstant(kWeakHeapObjectMask)),
|
||||
IntPtrConstant(0));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::ToStrongHeapObject(Node* value) {
|
||||
return BitcastWordToTagged(WordAnd(BitcastTaggedToWord(value),
|
||||
IntPtrConstant(~kWeakHeapObjectMask)));
|
||||
TNode<HeapObject> CodeStubAssembler::GetHeapObject(TNode<MaybeObject> value) {
|
||||
return UncheckedCast<HeapObject>(BitcastWordToTagged(WordAnd(
|
||||
BitcastMaybeObjectToWord(value), IntPtrConstant(~kWeakHeapObjectMask))));
|
||||
}
|
||||
|
||||
TNode<Object> CodeStubAssembler::LoadArrayElement(
|
||||
TNode<HeapObject> CodeStubAssembler::ToStrongHeapObject(
|
||||
TNode<MaybeObject> value) {
|
||||
AssertIsStrongHeapObject(value);
|
||||
return ReinterpretCast<HeapObject>(value);
|
||||
}
|
||||
|
||||
TNode<Object> CodeStubAssembler::ToStrongHeapObjectOrSmi(
|
||||
TNode<MaybeObject> value) {
|
||||
AssertIsStrongHeapObjectOrSmi(value);
|
||||
return ReinterpretCast<Object>(value);
|
||||
}
|
||||
|
||||
TNode<MaybeObject> CodeStubAssembler::LoadArrayElement(
|
||||
SloppyTNode<Object> object, int array_header_size, Node* index_node,
|
||||
int additional_offset, ParameterMode parameter_mode,
|
||||
LoadSensitivity needs_poisoning) {
|
||||
@ -1733,7 +1752,7 @@ TNode<Object> CodeStubAssembler::LoadArrayElement(
|
||||
int32_t header_size = array_header_size + additional_offset - kHeapObjectTag;
|
||||
TNode<IntPtrT> offset = ElementOffsetFromIndex(index_node, HOLEY_ELEMENTS,
|
||||
parameter_mode, header_size);
|
||||
return UncheckedCast<Object>(
|
||||
return UncheckedCast<MaybeObject>(
|
||||
Load(MachineType::AnyTagged(), object, offset, needs_poisoning));
|
||||
}
|
||||
|
||||
@ -1744,8 +1763,9 @@ TNode<Object> CodeStubAssembler::LoadFixedArrayElement(
|
||||
// and thus the reasonable assert IsFixedArraySubclass(object) is
|
||||
// untrue. TODO(marja): Fix.
|
||||
CSA_SLOW_ASSERT(this, IsNotWeakFixedArraySubclass(object));
|
||||
return LoadArrayElement(object, FixedArray::kHeaderSize, index_node,
|
||||
additional_offset, parameter_mode, needs_poisoning);
|
||||
return ToStrongHeapObjectOrSmi(
|
||||
LoadArrayElement(object, FixedArray::kHeaderSize, index_node,
|
||||
additional_offset, parameter_mode, needs_poisoning));
|
||||
}
|
||||
|
||||
TNode<RawPtrT> CodeStubAssembler::LoadFixedTypedArrayBackingStore(
|
||||
@ -6943,9 +6963,8 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
|
||||
|
||||
BuildFastLoop(last_exclusive, first_inclusive,
|
||||
[=](SloppyTNode<IntPtrT> name_index) {
|
||||
TNode<Name> candidate_name = CAST(
|
||||
LoadArrayElement(array, Array::kHeaderSize, name_index));
|
||||
CSA_ASSERT(this, IsStrongHeapObject(candidate_name));
|
||||
TNode<Name> candidate_name = CAST(ToStrongHeapObject(
|
||||
LoadArrayElement(array, Array::kHeaderSize, name_index)));
|
||||
*var_name_index = name_index;
|
||||
GotoIf(WordEqual(candidate_name, unique_name), if_found);
|
||||
},
|
||||
@ -7014,10 +7033,9 @@ TNode<Name> CodeStubAssembler::GetKey(TNode<Array> array,
|
||||
std::is_base_of<TransitionArray, Array>::value,
|
||||
"T must be a descendant of FixedArray or a TransitionArray");
|
||||
const int key_offset = Array::ToKeyIndex(0) * kPointerSize;
|
||||
TNode<Name> key =
|
||||
CAST(LoadArrayElement(array, Array::kHeaderSize,
|
||||
EntryIndexToIndex<Array>(entry_index), key_offset));
|
||||
CSA_ASSERT(this, IsStrongHeapObject(key));
|
||||
TNode<Name> key = CAST(ToStrongHeapObject(
|
||||
LoadArrayElement(array, Array::kHeaderSize,
|
||||
EntryIndexToIndex<Array>(entry_index), key_offset)));
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -11442,6 +11460,20 @@ void CodeStubAssembler::InitializeFunctionContext(Node* native_context,
|
||||
native_context);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::AssertIsStrongHeapObject(
|
||||
SloppyTNode<MaybeObject> object) {
|
||||
CSA_SLOW_ASSERT(this, WordEqual(WordAnd(BitcastMaybeObjectToWord(object),
|
||||
IntPtrConstant(kHeapObjectTagMask)),
|
||||
IntPtrConstant(kHeapObjectTag)));
|
||||
}
|
||||
|
||||
void CodeStubAssembler::AssertIsStrongHeapObjectOrSmi(
|
||||
SloppyTNode<MaybeObject> object) {
|
||||
CSA_SLOW_ASSERT(this, WordEqual(WordAnd(BitcastMaybeObjectToWord(object),
|
||||
IntPtrConstant(kWeakHeapObjectMask)),
|
||||
IntPtrConstant(0)));
|
||||
}
|
||||
|
||||
void CodeStubAssembler::AssertIsStrongHeapObject(
|
||||
SloppyTNode<HeapObject> object) {
|
||||
CSA_SLOW_ASSERT(this, WordEqual(WordAnd(BitcastTaggedToWord(object),
|
||||
|
@ -436,6 +436,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
|
||||
// Check a value for smi-ness
|
||||
TNode<BoolT> TaggedIsSmi(SloppyTNode<Object> a);
|
||||
TNode<BoolT> TaggedIsSmi(TNode<MaybeObject> a);
|
||||
TNode<BoolT> TaggedIsNotSmi(SloppyTNode<Object> a);
|
||||
// Check that the value is a non-negative smi.
|
||||
TNode<BoolT> TaggedIsPositiveSmi(SloppyTNode<Object> a);
|
||||
@ -537,6 +538,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Load a SMI root, untag it, and convert to Word32.
|
||||
Node* LoadAndUntagToWord32Root(Heap::RootListIndex root_index);
|
||||
|
||||
TNode<MaybeObject> LoadMaybeWeakObjectField(SloppyTNode<HeapObject> object,
|
||||
int offset) {
|
||||
return UncheckedCast<MaybeObject>(
|
||||
LoadObjectField(object, offset, MachineType::AnyTagged()));
|
||||
}
|
||||
|
||||
// Tag a smi and store it.
|
||||
Node* StoreAndTagSmi(Node* base, int offset, Node* value);
|
||||
|
||||
@ -647,14 +654,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// pointed to)
|
||||
// - a strong reference (jump to "if_strong", "extracted" will be the object
|
||||
// pointed to)
|
||||
void DispatchMaybeObject(Node* maybe_object, Label* if_smi, Label* if_cleared,
|
||||
Label* if_weak, Label* if_strong,
|
||||
Variable* extracted);
|
||||
Node* IsStrongHeapObject(Node* value);
|
||||
Node* ToStrongHeapObject(Node* value);
|
||||
void DispatchMaybeObject(TNode<MaybeObject> maybe_object, Label* if_smi,
|
||||
Label* if_cleared, Label* if_weak, Label* if_strong,
|
||||
TVariable<Object>* extracted);
|
||||
TNode<BoolT> IsStrongHeapObject(TNode<MaybeObject> value);
|
||||
TNode<HeapObject> GetHeapObject(TNode<MaybeObject> value);
|
||||
TNode<HeapObject> ToStrongHeapObject(TNode<MaybeObject> value);
|
||||
TNode<Object> ToStrongHeapObjectOrSmi(TNode<MaybeObject> value);
|
||||
|
||||
// Load an array element from a FixedArray / WeakFixedArray.
|
||||
TNode<Object> LoadArrayElement(
|
||||
TNode<MaybeObject> LoadArrayElement(
|
||||
SloppyTNode<Object> object, int array_header_size, Node* index,
|
||||
int additional_offset = 0,
|
||||
ParameterMode parameter_mode = INTPTR_PARAMETERS,
|
||||
@ -2290,6 +2299,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
void InitializeFunctionContext(Node* native_context, Node* context,
|
||||
int slots);
|
||||
|
||||
void AssertIsStrongHeapObject(SloppyTNode<MaybeObject> object);
|
||||
void AssertIsStrongHeapObjectOrSmi(SloppyTNode<MaybeObject> object);
|
||||
void AssertIsStrongHeapObject(SloppyTNode<HeapObject> object);
|
||||
|
||||
private:
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "src/machine-type.h"
|
||||
#include "src/objects/data-handler.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/maybe-object.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
#include "src/zone/zone-containers.h"
|
||||
|
||||
@ -156,8 +157,10 @@ template <class T>
|
||||
struct is_valid_type_tag {
|
||||
static const bool value = std::is_base_of<Object, T>::value ||
|
||||
std::is_base_of<UntaggedT, T>::value ||
|
||||
std::is_base_of<MaybeObject, T>::value ||
|
||||
std::is_same<ExternalReference, T>::value;
|
||||
static const bool is_tagged = std::is_base_of<Object, T>::value;
|
||||
static const bool is_tagged = std::is_base_of<Object, T>::value ||
|
||||
std::is_base_of<MaybeObject, T>::value;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
@ -485,6 +488,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
|
||||
V(Float64ExtractLowWord32, Word32T, Float64T) \
|
||||
V(Float64ExtractHighWord32, Word32T, Float64T) \
|
||||
V(BitcastTaggedToWord, IntPtrT, Object) \
|
||||
V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \
|
||||
V(BitcastWordToTagged, Object, WordT) \
|
||||
V(BitcastWordToTaggedSigned, Smi, WordT) \
|
||||
V(TruncateFloat64ToFloat32, Float32T, Float64T) \
|
||||
|
@ -701,6 +701,14 @@ struct MachineOperatorGlobalCache {
|
||||
};
|
||||
BitcastTaggedToWordOperator kBitcastTaggedToWord;
|
||||
|
||||
struct BitcastMaybeObjectToWordOperator : public Operator {
|
||||
BitcastMaybeObjectToWordOperator()
|
||||
: Operator(IrOpcode::kBitcastTaggedToWord,
|
||||
Operator::kEliminatable | Operator::kNoWrite,
|
||||
"BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {}
|
||||
};
|
||||
BitcastMaybeObjectToWordOperator kBitcastMaybeObjectToWord;
|
||||
|
||||
struct PoisonOnSpeculationTagged : public Operator {
|
||||
PoisonOnSpeculationTagged()
|
||||
: Operator(IrOpcode::kPoisonOnSpeculationTagged,
|
||||
@ -912,6 +920,10 @@ const Operator* MachineOperatorBuilder::BitcastTaggedToWord() {
|
||||
return &cache_.kBitcastTaggedToWord;
|
||||
}
|
||||
|
||||
const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() {
|
||||
return &cache_.kBitcastMaybeObjectToWord;
|
||||
}
|
||||
|
||||
const Operator* MachineOperatorBuilder::DebugAbort() {
|
||||
return &cache_.kDebugAbort;
|
||||
}
|
||||
|
@ -301,6 +301,10 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
|
||||
// This operator reinterprets the bits of a tagged pointer as word.
|
||||
const Operator* BitcastTaggedToWord();
|
||||
|
||||
// This operator reinterprets the bits of a tagged MaybeObject pointer as
|
||||
// word.
|
||||
const Operator* BitcastMaybeObjectToWord();
|
||||
|
||||
// This operator reinterprets the bits of a word as tagged pointer.
|
||||
const Operator* BitcastWordToTagged();
|
||||
|
||||
|
@ -578,6 +578,13 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
|
||||
return AddNode(machine()->BitcastTaggedToWord(), a);
|
||||
#else
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
Node* BitcastMaybeObjectToWord(Node* a) {
|
||||
#ifdef ENABLE_VERIFY_CSA
|
||||
return AddNode(machine()->BitcastMaybeObjectToWord(), a);
|
||||
#else
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
Node* BitcastWordToTagged(Node* a) {
|
||||
|
@ -684,14 +684,14 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
TVARIABLE(Map, var_transition_map);
|
||||
Label simple_transition(this), transition_array(this),
|
||||
found_handler_candidate(this);
|
||||
TNode<Object> maybe_handler =
|
||||
LoadObjectField(receiver_map, Map::kTransitionsOrPrototypeInfoOffset);
|
||||
TNode<MaybeObject> maybe_handler = LoadMaybeWeakObjectField(
|
||||
receiver_map, Map::kTransitionsOrPrototypeInfoOffset);
|
||||
|
||||
// SMI -> slow
|
||||
// cleared weak reference -> slow
|
||||
// weak reference -> simple_transition
|
||||
// strong reference -> transition_array
|
||||
VARIABLE(var_transition_map_or_array, MachineRepresentation::kTagged);
|
||||
TVARIABLE(Object, var_transition_map_or_array);
|
||||
DispatchMaybeObject(maybe_handler, slow, slow, &simple_transition,
|
||||
&transition_array, &var_transition_map_or_array);
|
||||
|
||||
@ -732,7 +732,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
const int kKeyToTargetOffset = (TransitionArray::kEntryTargetIndex -
|
||||
TransitionArray::kEntryKeyIndex) *
|
||||
kPointerSize;
|
||||
var_transition_map = CAST(ToStrongHeapObject(
|
||||
var_transition_map = CAST(GetHeapObject(
|
||||
LoadArrayElement(transitions, WeakFixedArray::kHeaderSize,
|
||||
var_name_index.value(), kKeyToTargetOffset)));
|
||||
Goto(&found_handler_candidate);
|
||||
|
@ -91,6 +91,11 @@ HeapObject* MaybeObject::GetHeapObject() {
|
||||
return RemoveWeakHeapObjectMask(reinterpret_cast<HeapObjectReference*>(this));
|
||||
}
|
||||
|
||||
MaybeObject* MaybeObject::MakeWeak(MaybeObject* object) {
|
||||
DCHECK(object->IsStrongOrWeakHeapObject());
|
||||
return AddWeakHeapObjectMask(object);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -50,10 +50,7 @@ class MaybeObject {
|
||||
return reinterpret_cast<MaybeObject*>(object);
|
||||
}
|
||||
|
||||
static MaybeObject* MakeWeak(MaybeObject* object) {
|
||||
DCHECK(object->IsStrongOrWeakHeapObject());
|
||||
return AddWeakHeapObjectMask(object);
|
||||
}
|
||||
static inline MaybeObject* MakeWeak(MaybeObject* object);
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
static void VerifyMaybeObjectPointer(MaybeObject* p);
|
||||
|
Loading…
Reference in New Issue
Block a user