Commit fd4cc2b2 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr][csa] Preparing for smi-corrupting decompression

This CL fixes comparison operations that take into account full-word
value instead of the lower 32 bits and tweaks some CSA helper functions
for smi-corrupting decompression.

Bug: v8:9706
Change-Id: I50e38a9f34b911ec0b8dd4e21298417bf23160aa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1824943Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63995}
parent dcf3b663
...@@ -112,6 +112,8 @@ using PlatformSmiTagging = SmiTagging<kApiInt32Size>; ...@@ -112,6 +112,8 @@ using PlatformSmiTagging = SmiTagging<kApiInt32Size>;
using PlatformSmiTagging = SmiTagging<kApiTaggedSize>; using PlatformSmiTagging = SmiTagging<kApiTaggedSize>;
#endif #endif
// TODO(ishell): Consinder adding kSmiShiftBits = kSmiShiftSize + kSmiTagSize
// since it's used much more often than the inividual constants.
const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
const int kSmiMinValue = static_cast<int>(PlatformSmiTagging::kSmiMinValue); const int kSmiMinValue = static_cast<int>(PlatformSmiTagging::kSmiMinValue);
......
...@@ -2615,6 +2615,7 @@ extern macro BitcastWordToTaggedSigned(uintptr): Smi; ...@@ -2615,6 +2615,7 @@ extern macro BitcastWordToTaggedSigned(uintptr): Smi;
extern macro BitcastWordToTagged(intptr): Object; extern macro BitcastWordToTagged(intptr): Object;
extern macro BitcastWordToTagged(uintptr): Object; extern macro BitcastWordToTagged(uintptr): Object;
extern macro BitcastTaggedToWord(Tagged): intptr; extern macro BitcastTaggedToWord(Tagged): intptr;
extern macro BitcastTaggedToWordForTagAndSmiBits(Tagged): intptr;
intrinsic %FromConstexpr<To: type, From: type>(b: From): To; intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
macro FromConstexpr<To: type, From: type>(o: From): To; macro FromConstexpr<To: type, From: type>(o: From): To;
......
...@@ -1101,7 +1101,7 @@ TF_BUILTIN(CreateObjectWithoutProperties, ObjectBuiltinsAssembler) { ...@@ -1101,7 +1101,7 @@ TF_BUILTIN(CreateObjectWithoutProperties, ObjectBuiltinsAssembler) {
LoadMapPrototypeInfo(LoadMap(CAST(prototype)), &call_runtime); LoadMapPrototypeInfo(LoadMap(CAST(prototype)), &call_runtime);
TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField( TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField(
prototype_info, PrototypeInfo::kObjectCreateMapOffset); prototype_info, PrototypeInfo::kObjectCreateMapOffset);
GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), &call_runtime); GotoIf(TaggedEqual(maybe_map, UndefinedConstant()), &call_runtime);
map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime));
Goto(&instantiate_map); Goto(&instantiate_map);
} }
...@@ -1197,8 +1197,7 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { ...@@ -1197,8 +1197,7 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
Comment("Load ObjectCreateMap from PrototypeInfo"); Comment("Load ObjectCreateMap from PrototypeInfo");
TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField( TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField(
prototype_info, PrototypeInfo::kObjectCreateMapOffset); prototype_info, PrototypeInfo::kObjectCreateMapOffset);
GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), GotoIf(TaggedEqual(maybe_map, UndefinedConstant()), &call_runtime);
&call_runtime);
map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime));
Goto(&instantiate_map); Goto(&instantiate_map);
} }
......
...@@ -77,7 +77,7 @@ class BuiltinArguments : public Arguments { ...@@ -77,7 +77,7 @@ class BuiltinArguments : public Arguments {
RuntimeCallCounterId::kBuiltin_##name); \ RuntimeCallCounterId::kBuiltin_##name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Builtin_" #name); \ "V8.Builtin_" #name); \
return Builtin_Impl_##name(args, isolate).ptr(); \ return CONVERT_OBJECT(Builtin_Impl_##name(args, isolate)); \
} \ } \
\ \
V8_WARN_UNUSED_RESULT Address Builtin_##name( \ V8_WARN_UNUSED_RESULT Address Builtin_##name( \
...@@ -87,7 +87,7 @@ class BuiltinArguments : public Arguments { ...@@ -87,7 +87,7 @@ class BuiltinArguments : public Arguments {
return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \ return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \
} \ } \
BuiltinArguments args(args_length, args_object); \ BuiltinArguments args(args_length, args_object); \
return Builtin_Impl_##name(args, isolate).ptr(); \ return CONVERT_OBJECT(Builtin_Impl_##name(args, isolate)); \
} \ } \
\ \
V8_WARN_UNUSED_RESULT static Object Builtin_Impl_##name( \ V8_WARN_UNUSED_RESULT static Object Builtin_Impl_##name( \
......
...@@ -24,8 +24,8 @@ Cast<FrameType>(o: Object): FrameType ...@@ -24,8 +24,8 @@ Cast<FrameType>(o: Object): FrameType
labels CastError { labels CastError {
if (TaggedIsNotSmi(o)) goto CastError; if (TaggedIsNotSmi(o)) goto CastError;
assert( assert(
(Convert<uintptr>(BitcastTaggedToWord(o)) >>> kSmiTagSize) < Convert<int32>(BitcastTaggedToWordForTagAndSmiBits(o)) <
kFrameTypeCount); Convert<int32>(kFrameTypeCount << kSmiTagSize));
return %RawDownCast<FrameType>(o); return %RawDownCast<FrameType>(o);
} }
......
...@@ -23,7 +23,7 @@ namespace typed_array_slice { ...@@ -23,7 +23,7 @@ namespace typed_array_slice {
// of src and result array are the same and they are not sharing the // of src and result array are the same and they are not sharing the
// same buffer, use memmove. // same buffer, use memmove.
if (srcKind != destInfo.kind) goto IfSlow; if (srcKind != destInfo.kind) goto IfSlow;
if (BitcastTaggedToWord(dest.buffer) == BitcastTaggedToWord(src.buffer)) { if (dest.buffer == src.buffer) {
goto IfSlow; goto IfSlow;
} }
......
This diff is collapsed.
...@@ -366,6 +366,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -366,6 +366,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
#error Unknown architecture. #error Unknown architecture.
#endif #endif
// Pointer compression specific. Returns true if the upper 32 bits of a Smi
// contain the sign of a lower 32 bits (i.e. not corrupted) so that the Smi
// can be directly used as an index in element offset computation.
TNode<BoolT> IsValidSmiIndex(TNode<Smi> smi);
// Pointer compression specific. Ensures that the upper 32 bits of a Smi
// contain the sign of a lower 32 bits so that the Smi can be directly used
// as an index in element offset computation.
TNode<Smi> NormalizeSmiIndex(TNode<Smi> smi_index);
TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) { TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) {
GotoIf(TaggedIsNotSmi(value), fail); GotoIf(TaggedIsNotSmi(value), fail);
return UncheckedCast<Smi>(value); return UncheckedCast<Smi>(value);
...@@ -1223,7 +1233,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -1223,7 +1233,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsWeakOrCleared(TNode<MaybeObject> value); TNode<BoolT> IsWeakOrCleared(TNode<MaybeObject> value);
TNode<BoolT> IsCleared(TNode<MaybeObject> value); TNode<BoolT> IsCleared(TNode<MaybeObject> value);
TNode<BoolT> IsNotCleared(TNode<MaybeObject> value); TNode<BoolT> IsNotCleared(TNode<MaybeObject> value) {
return Word32BinaryNot(IsCleared(value));
}
// Removes the weak bit + asserts it was set. // Removes the weak bit + asserts it was set.
TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value); TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value);
...@@ -1231,12 +1243,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -1231,12 +1243,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value, TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value,
Label* if_cleared); Label* if_cleared);
TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> object, // Checks if |maybe_object| is a weak reference to given |heap_object|.
TNode<Object> value); // Works for both any tagged |maybe_object| values.
TNode<BoolT> IsNotWeakReferenceTo(TNode<MaybeObject> object, TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> maybe_object,
TNode<Object> value); TNode<HeapObject> heap_object);
TNode<BoolT> IsStrongReferenceTo(TNode<MaybeObject> object, // Returns true if the |object| is a HeapObject and |maybe_object| is a weak
TNode<Object> value); // reference to |object|.
// The |maybe_object| must not be a Smi.
TNode<BoolT> IsWeakReferenceToObject(TNode<MaybeObject> maybe_object,
TNode<Object> object);
TNode<MaybeObject> MakeWeak(TNode<HeapObject> value); TNode<MaybeObject> MakeWeak(TNode<HeapObject> value);
...@@ -1939,16 +1954,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -1939,16 +1954,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
enum class DestroySource { kNo, kYes }; enum class DestroySource { kNo, kYes };
// Collect the callable |target| feedback for either a CALL_IC or // Collect the callable |maybe_target| feedback for either a CALL_IC or
// an INSTANCEOF_IC in the |feedback_vector| at |slot_id|. // an INSTANCEOF_IC in the |feedback_vector| at |slot_id|.
void CollectCallableFeedback(TNode<Object> target, TNode<Context> context, void CollectCallableFeedback(TNode<Object> maybe_target,
TNode<Context> context,
TNode<FeedbackVector> feedback_vector, TNode<FeedbackVector> feedback_vector,
TNode<UintPtrT> slot_id); TNode<UintPtrT> slot_id);
// Collect CALL_IC feedback for |target| function in the // Collect CALL_IC feedback for |maybe_target| function in the
// |feedback_vector| at |slot_id|, and the call counts in // |feedback_vector| at |slot_id|, and the call counts in
// the |feedback_vector| at |slot_id+1|. // the |feedback_vector| at |slot_id+1|.
void CollectCallFeedback(TNode<Object> target, TNode<Context> context, void CollectCallFeedback(TNode<Object> maybe_target, TNode<Context> context,
TNode<HeapObject> maybe_feedback_vector, TNode<HeapObject> maybe_feedback_vector,
TNode<UintPtrT> slot_id); TNode<UintPtrT> slot_id);
...@@ -3697,7 +3713,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3697,7 +3713,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<AllocationSite> allocation_site, TNode<IntPtrT> size_in_bytes); TNode<AllocationSite> allocation_site, TNode<IntPtrT> size_in_bytes);
TNode<BoolT> IsValidSmi(TNode<Smi> smi); TNode<BoolT> IsValidSmi(TNode<Smi> smi);
Node* SmiShiftBitsConstant();
TNode<IntPtrT> SmiShiftBitsConstant() {
return IntPtrConstant(kSmiShiftSize + kSmiTagSize);
}
TNode<Int32T> SmiShiftBitsConstant32() {
return Int32Constant(kSmiShiftSize + kSmiTagSize);
}
// Emits keyed sloppy arguments load if the |value| is nullptr or store // Emits keyed sloppy arguments load if the |value| is nullptr or store
// otherwise. Returns either the loaded value or |value|. // otherwise. Returns either the loaded value or |value|.
......
...@@ -1546,14 +1546,17 @@ const Operator* RepresentationChanger::TaggedSignedOperatorFor( ...@@ -1546,14 +1546,17 @@ const Operator* RepresentationChanger::TaggedSignedOperatorFor(
IrOpcode::Value opcode) { IrOpcode::Value opcode) {
switch (opcode) { switch (opcode) {
case IrOpcode::kSpeculativeNumberLessThan: case IrOpcode::kSpeculativeNumberLessThan:
return machine()->Is32() ? machine()->Int32LessThan() return (COMPRESS_POINTERS_BOOL || machine()->Is32())
: machine()->Int64LessThan(); ? machine()->Int32LessThan()
: machine()->Int64LessThan();
case IrOpcode::kSpeculativeNumberLessThanOrEqual: case IrOpcode::kSpeculativeNumberLessThanOrEqual:
return machine()->Is32() ? machine()->Int32LessThanOrEqual() return (COMPRESS_POINTERS_BOOL || machine()->Is32())
: machine()->Int64LessThanOrEqual(); ? machine()->Int32LessThanOrEqual()
: machine()->Int64LessThanOrEqual();
case IrOpcode::kSpeculativeNumberEqual: case IrOpcode::kSpeculativeNumberEqual:
return machine()->Is32() ? machine()->Word32Equal() return (COMPRESS_POINTERS_BOOL || machine()->Is32())
: machine()->Word64Equal(); ? machine()->Word32Equal()
: machine()->Word64Equal();
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -1669,8 +1669,8 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData( ...@@ -1669,8 +1669,8 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData(
Object OptimizedFrame::receiver() const { Object OptimizedFrame::receiver() const {
Code code = LookupCode(); Code code = LookupCode();
if (code.kind() == Code::BUILTIN) { if (code.kind() == Code::BUILTIN) {
Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset; intptr_t argc = static_cast<int>(
intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr); Memory<intptr_t>(fp() + OptimizedBuiltinFrameConstants::kArgCOffset));
intptr_t args_size = intptr_t args_size =
(StandardFrameConstants::kFixedSlotCountAboveFp + argc) * (StandardFrameConstants::kFixedSlotCountAboveFp + argc) *
kSystemPointerSize; kSystemPointerSize;
......
...@@ -82,7 +82,7 @@ TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase( ...@@ -82,7 +82,7 @@ TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase(
// Try to quickly handle the monomorphic case without knowing for sure // Try to quickly handle the monomorphic case without knowing for sure
// if we have a weak reference in feedback. // if we have a weak reference in feedback.
GotoIf(IsNotWeakReferenceTo(feedback, receiver_map), if_miss); GotoIfNot(IsWeakReferenceTo(feedback, receiver_map), if_miss);
TNode<MaybeObject> handler = UncheckedCast<MaybeObject>( TNode<MaybeObject> handler = UncheckedCast<MaybeObject>(
Load(MachineType::AnyTagged(), vector, Load(MachineType::AnyTagged(), vector,
...@@ -117,7 +117,7 @@ void AccessorAssembler::HandlePolymorphicCase( ...@@ -117,7 +117,7 @@ void AccessorAssembler::HandlePolymorphicCase(
TNode<MaybeObject> maybe_cached_map = TNode<MaybeObject> maybe_cached_map =
LoadWeakFixedArrayElement(feedback, var_index.value()); LoadWeakFixedArrayElement(feedback, var_index.value());
CSA_ASSERT(this, IsWeakOrCleared(maybe_cached_map)); CSA_ASSERT(this, IsWeakOrCleared(maybe_cached_map));
GotoIf(IsNotWeakReferenceTo(maybe_cached_map, receiver_map), &loop_next); GotoIfNot(IsWeakReferenceTo(maybe_cached_map, receiver_map), &loop_next);
// Found, now call handler. // Found, now call handler.
TNode<MaybeObject> handler = TNode<MaybeObject> handler =
...@@ -850,7 +850,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( ...@@ -850,7 +850,7 @@ void AccessorAssembler::HandleLoadICProtoHandler(
Label load_from_cached_holder(this), is_smi(this), done(this); Label load_from_cached_holder(this), is_smi(this), done(this);
GotoIf(TaggedIsSmi(maybe_holder_or_constant), &is_smi); GotoIf(TaggedIsSmi(maybe_holder_or_constant), &is_smi);
Branch(IsStrongReferenceTo(maybe_holder_or_constant, NullConstant()), &done, Branch(TaggedEqual(maybe_holder_or_constant, NullConstant()), &done,
&load_from_cached_holder); &load_from_cached_holder);
BIND(&is_smi); BIND(&is_smi);
...@@ -1192,13 +1192,13 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, ...@@ -1192,13 +1192,13 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors,
DCHECK_NE(static_cast<uint32_t>(kNoneType), kClearedWeakHeapObjectLower32); DCHECK_NE(static_cast<uint32_t>(kNoneType), kClearedWeakHeapObjectLower32);
DCHECK_NE(static_cast<uint32_t>(kAnyType), kClearedWeakHeapObjectLower32); DCHECK_NE(static_cast<uint32_t>(kAnyType), kClearedWeakHeapObjectLower32);
// FieldType::None can't hold any value. // FieldType::None can't hold any value.
GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), GotoIf(
IntPtrConstant(kNoneType)), TaggedEqual(field_type, BitcastWordToTagged(IntPtrConstant(kNoneType))),
bailout); bailout);
// FieldType::Any can hold any value. // FieldType::Any can hold any value.
GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), GotoIf(
IntPtrConstant(kAnyType)), TaggedEqual(field_type, BitcastWordToTagged(IntPtrConstant(kAnyType))),
&all_fine); &all_fine);
// Cleared weak references count as FieldType::None, which can't hold any // Cleared weak references count as FieldType::None, which can't hold any
// value. // value.
TNode<Map> field_type_map = TNode<Map> field_type_map =
......
...@@ -834,7 +834,8 @@ TNode<Object> InterpreterAssembler::Construct( ...@@ -834,7 +834,8 @@ TNode<Object> InterpreterAssembler::Construct(
// Check if we have monomorphic {new_target} feedback already. // Check if we have monomorphic {new_target} feedback already.
TNode<MaybeObject> feedback = TNode<MaybeObject> feedback =
LoadFeedbackVectorSlot(feedback_vector, slot_id); LoadFeedbackVectorSlot(feedback_vector, slot_id);
Branch(IsWeakReferenceTo(feedback, new_target), &construct, &extra_checks); Branch(IsWeakReferenceToObject(feedback, new_target), &construct,
&extra_checks);
BIND(&extra_checks); BIND(&extra_checks);
{ {
...@@ -1016,7 +1017,8 @@ TNode<Object> InterpreterAssembler::ConstructWithSpread( ...@@ -1016,7 +1017,8 @@ TNode<Object> InterpreterAssembler::ConstructWithSpread(
// Check if we have monomorphic {new_target} feedback already. // Check if we have monomorphic {new_target} feedback already.
TNode<MaybeObject> feedback = TNode<MaybeObject> feedback =
LoadFeedbackVectorSlot(feedback_vector, slot_id); LoadFeedbackVectorSlot(feedback_vector, slot_id);
Branch(IsWeakReferenceTo(feedback, new_target), &construct, &extra_checks); Branch(IsWeakReferenceToObject(feedback, new_target), &construct,
&extra_checks);
BIND(&extra_checks); BIND(&extra_checks);
{ {
......
...@@ -176,7 +176,8 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) { ...@@ -176,7 +176,8 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
} else { } else {
// If no serializer is provided and the field was empty, we serialize it // If no serializer is provided and the field was empty, we serialize it
// by default to nullptr. // by default to nullptr.
if (serialize_embedder_fields_.callback == nullptr && object.ptr() == 0) { if (serialize_embedder_fields_.callback == nullptr &&
object == Smi::zero()) {
serialized_data.push_back({nullptr, 0}); serialized_data.push_back({nullptr, 0});
} else { } else {
DCHECK_NOT_NULL(serialize_embedder_fields_.callback); DCHECK_NOT_NULL(serialize_embedder_fields_.callback);
......
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
#include "src/base/ieee754.h" #include "src/base/ieee754.h"
#include "src/base/overflowing-math.h" #include "src/base/overflowing-math.h"
#include "src/base/utils/random-number-generator.h" #include "src/base/utils/random-number-generator.h"
#include "src/common/ptr-compr-inl.h"
#include "src/objects/objects-inl.h"
#include "src/utils/boxed-float.h" #include "src/utils/boxed-float.h"
#include "src/utils/utils.h" #include "src/utils/utils.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/value-helper.h" #include "test/cctest/compiler/value-helper.h"
...@@ -410,11 +411,12 @@ TEST(CompressDecompressTaggedAnyPointer) { ...@@ -410,11 +411,12 @@ TEST(CompressDecompressTaggedAnyPointer) {
} }
TEST(CompressDecompressTaggedAnySigned) { TEST(CompressDecompressTaggedAnySigned) {
RawMachineAssemblerTester<int64_t> m; RawMachineAssemblerTester<Address> m;
Smi smi = Smi::FromInt(123); Smi smi = Smi::FromInt(123);
int64_t smiPointer = static_cast<int64_t>(smi.ptr()); Node* node = m.Int64Constant(static_cast<int64_t>(smi.ptr()));
Node* node = m.Int64Constant(smiPointer);
m.Return(m.ChangeCompressedToTagged(m.ChangeTaggedToCompressed(node))); m.Return(m.ChangeCompressedToTagged(m.ChangeTaggedToCompressed(node)));
Address smiPointer =
DecompressTaggedAny(m.isolate(), CompressTagged(smi.ptr()));
CHECK_EQ(smiPointer, m.Call()); CHECK_EQ(smiPointer, m.Call());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment