Revert "Introduce MutableHeapNumber class."
This reverts commit 40ac6b187a
.
Reason for revert: https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux%20-%20debug/21009
Original change's description:
> Introduce MutableHeapNumber class.
>
> V8 knows heap numbers and mutable heap numbers. They have
> difference instance types, but in C++ code we've used the
> same class for both (HeapNumber). Confusingly, however,
> IsHeapNumber would return false for mutable heap numbers,
> while HeapNumber::cast would succeed.
>
> This CL adds a separate class MutableHeapNumber and
> eliminates the confusing behavior.
>
> TBR=bmeurer@chromium.org
>
> Change-Id: Id894d177c7fe8cc3f451be80c273b50daee91378
> Reviewed-on: https://chromium-review.googlesource.com/1113544
> Commit-Queue: Georg Neis <neis@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#54012}
TBR=ulan@chromium.org,jarin@chromium.org,neis@chromium.org,bmeurer@chromium.org
Change-Id: I358a822f20b9110def968e69463a753a2a32c68c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/1114538
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54013}
This commit is contained in:
parent
40ac6b187a
commit
983456f5b8
@ -477,8 +477,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Handle<HeapObject> object;
|
Handle<HeapObject> object;
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
break;
|
break;
|
||||||
case HeapObjectRequest::kCodeStub:
|
case HeapObjectRequest::kCodeStub:
|
||||||
request.code_stub()->set_isolate(isolate);
|
request.code_stub()->set_isolate(isolate);
|
||||||
|
@ -591,8 +591,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
|
Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber: {
|
case HeapObjectRequest::kHeapNumber: {
|
||||||
Handle<HeapObject> object =
|
Handle<HeapObject> object = isolate->factory()->NewHeapNumber(
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
request.heap_number(), IMMUTABLE, TENURED);
|
||||||
set_target_address_at(pc, 0 /* unused */, object.address());
|
set_target_address_at(pc, 0 /* unused */, object.address());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral(
|
|||||||
{
|
{
|
||||||
Node* double_value = LoadHeapNumberValue(field);
|
Node* double_value = LoadHeapNumberValue(field);
|
||||||
Node* mutable_heap_number =
|
Node* mutable_heap_number =
|
||||||
AllocateMutableHeapNumberWithValue(double_value);
|
AllocateHeapNumberWithValue(double_value, MUTABLE);
|
||||||
StoreObjectField(copy, offset, mutable_heap_number);
|
StoreObjectField(copy, offset, mutable_heap_number);
|
||||||
Goto(&continue_loop);
|
Goto(&continue_loop);
|
||||||
}
|
}
|
||||||
|
@ -2439,12 +2439,6 @@ void CodeStubAssembler::StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
|
|||||||
MachineRepresentation::kFloat64);
|
MachineRepresentation::kFloat64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::StoreMutableHeapNumberValue(
|
|
||||||
SloppyTNode<MutableHeapNumber> object, SloppyTNode<Float64T> value) {
|
|
||||||
StoreObjectFieldNoWriteBarrier(object, MutableHeapNumber::kValueOffset, value,
|
|
||||||
MachineRepresentation::kFloat64);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* CodeStubAssembler::StoreObjectField(
|
Node* CodeStubAssembler::StoreObjectField(
|
||||||
Node* object, int offset, Node* value) {
|
Node* object, int offset, Node* value) {
|
||||||
DCHECK_NE(HeapObject::kMapOffset, offset); // Use StoreMap instead.
|
DCHECK_NE(HeapObject::kMapOffset, offset); // Use StoreMap instead.
|
||||||
@ -2783,34 +2777,22 @@ Node* CodeStubAssembler::StoreCellValue(Node* cell, Node* value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumber() {
|
TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
|
||||||
Node* result = Allocate(HeapNumber::kSize, kNone);
|
Node* result = Allocate(HeapNumber::kSize, kNone);
|
||||||
Heap::RootListIndex heap_map_index = Heap::kHeapNumberMapRootIndex;
|
Heap::RootListIndex heap_map_index =
|
||||||
|
mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex
|
||||||
|
: Heap::kMutableHeapNumberMapRootIndex;
|
||||||
StoreMapNoWriteBarrier(result, heap_map_index);
|
StoreMapNoWriteBarrier(result, heap_map_index);
|
||||||
return UncheckedCast<HeapNumber>(result);
|
return UncheckedCast<HeapNumber>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumberWithValue(
|
TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumberWithValue(
|
||||||
SloppyTNode<Float64T> value) {
|
SloppyTNode<Float64T> value, MutableMode mode) {
|
||||||
TNode<HeapNumber> result = AllocateHeapNumber();
|
TNode<HeapNumber> result = AllocateHeapNumber(mode);
|
||||||
StoreHeapNumberValue(result, value);
|
StoreHeapNumberValue(result, value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<MutableHeapNumber> CodeStubAssembler::AllocateMutableHeapNumber() {
|
|
||||||
Node* result = Allocate(MutableHeapNumber::kSize, kNone);
|
|
||||||
Heap::RootListIndex heap_map_index = Heap::kMutableHeapNumberMapRootIndex;
|
|
||||||
StoreMapNoWriteBarrier(result, heap_map_index);
|
|
||||||
return UncheckedCast<MutableHeapNumber>(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<MutableHeapNumber> CodeStubAssembler::AllocateMutableHeapNumberWithValue(
|
|
||||||
SloppyTNode<Float64T> value) {
|
|
||||||
TNode<MutableHeapNumber> result = AllocateMutableHeapNumber();
|
|
||||||
StoreMutableHeapNumberValue(result, value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<BigInt> CodeStubAssembler::AllocateBigInt(TNode<IntPtrT> length) {
|
TNode<BigInt> CodeStubAssembler::AllocateBigInt(TNode<IntPtrT> length) {
|
||||||
TNode<BigInt> result = AllocateRawBigInt(length);
|
TNode<BigInt> result = AllocateRawBigInt(length);
|
||||||
StoreBigIntBitfield(result, WordShl(length, BigInt::LengthBits::kShift));
|
StoreBigIntBitfield(result, WordShl(length, BigInt::LengthBits::kShift));
|
||||||
|
@ -1075,8 +1075,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
// Store the floating point value of a HeapNumber.
|
// Store the floating point value of a HeapNumber.
|
||||||
void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
|
void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
|
||||||
SloppyTNode<Float64T> value);
|
SloppyTNode<Float64T> value);
|
||||||
void StoreMutableHeapNumberValue(SloppyTNode<MutableHeapNumber> object,
|
|
||||||
SloppyTNode<Float64T> value);
|
|
||||||
// Store a field to an object on the heap.
|
// Store a field to an object on the heap.
|
||||||
Node* StoreObjectField(Node* object, int offset, Node* value);
|
Node* StoreObjectField(Node* object, int offset, Node* value);
|
||||||
Node* StoreObjectField(Node* object, Node* offset, Node* value);
|
Node* StoreObjectField(Node* object, Node* offset, Node* value);
|
||||||
@ -1162,16 +1160,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||||
|
|
||||||
// Allocate a HeapNumber without initializing its value.
|
// Allocate a HeapNumber without initializing its value.
|
||||||
TNode<HeapNumber> AllocateHeapNumber();
|
TNode<HeapNumber> AllocateHeapNumber(MutableMode mode = IMMUTABLE);
|
||||||
// Allocate a HeapNumber with a specific value.
|
// Allocate a HeapNumber with a specific value.
|
||||||
TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value);
|
TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value,
|
||||||
TNode<HeapNumber> AllocateHeapNumberWithValue(double value) {
|
MutableMode mode = IMMUTABLE);
|
||||||
return AllocateHeapNumberWithValue(Float64Constant(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate a MutableHeapNumber with a specific value.
|
|
||||||
TNode<MutableHeapNumber> AllocateMutableHeapNumberWithValue(
|
|
||||||
SloppyTNode<Float64T> value);
|
|
||||||
|
|
||||||
// Allocate a BigInt with {length} digits. Sets the sign bit to {false}.
|
// Allocate a BigInt with {length} digits. Sets the sign bit to {false}.
|
||||||
// Does not initialize the digits.
|
// Does not initialize the digits.
|
||||||
@ -1184,6 +1176,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
TNode<WordT> LoadBigIntBitfield(TNode<BigInt> bigint);
|
TNode<WordT> LoadBigIntBitfield(TNode<BigInt> bigint);
|
||||||
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
|
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
|
||||||
|
|
||||||
|
TNode<HeapNumber> AllocateHeapNumberWithValue(double value,
|
||||||
|
MutableMode mode = IMMUTABLE) {
|
||||||
|
return AllocateHeapNumberWithValue(Float64Constant(value), mode);
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate a SeqOneByteString with the given length.
|
// Allocate a SeqOneByteString with the given length.
|
||||||
TNode<String> AllocateSeqOneByteString(int length,
|
TNode<String> AllocateSeqOneByteString(int length,
|
||||||
AllocationFlags flags = kNone);
|
AllocationFlags flags = kNone);
|
||||||
@ -2743,9 +2740,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
TNode<Smi> length, TNode<String> first,
|
TNode<Smi> length, TNode<String> first,
|
||||||
TNode<String> second, AllocationFlags flags);
|
TNode<String> second, AllocationFlags flags);
|
||||||
|
|
||||||
// Allocate a MutableHeapNumber without initializing its value.
|
|
||||||
TNode<MutableHeapNumber> AllocateMutableHeapNumber();
|
|
||||||
|
|
||||||
Node* SelectImpl(TNode<BoolT> condition, const NodeGenerator& true_body,
|
Node* SelectImpl(TNode<BoolT> condition, const NodeGenerator& true_body,
|
||||||
const NodeGenerator& false_body, MachineRepresentation rep);
|
const NodeGenerator& false_body, MachineRepresentation rep);
|
||||||
|
|
||||||
|
@ -266,8 +266,8 @@ TNode<Number> CodeAssembler::NumberConstant(double value) {
|
|||||||
// deferring allocation to code generation
|
// deferring allocation to code generation
|
||||||
// (see AllocateAndInstallRequestedHeapObjects) since that makes it easier
|
// (see AllocateAndInstallRequestedHeapObjects) since that makes it easier
|
||||||
// to generate constant lookups for embedded builtins.
|
// to generate constant lookups for embedded builtins.
|
||||||
return UncheckedCast<Number>(
|
return UncheckedCast<Number>(HeapConstant(
|
||||||
HeapConstant(isolate()->factory()->NewHeapNumber(value, TENURED)));
|
isolate()->factory()->NewHeapNumber(value, IMMUTABLE, TENURED)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3464,9 +3464,9 @@ void TranslatedState::MaterializeMutableHeapNumber(TranslatedFrame* frame,
|
|||||||
CHECK_NE(TranslatedValue::kCapturedObject,
|
CHECK_NE(TranslatedValue::kCapturedObject,
|
||||||
frame->values_[*value_index].kind());
|
frame->values_[*value_index].kind());
|
||||||
Handle<Object> value = frame->values_[*value_index].GetValue();
|
Handle<Object> value = frame->values_[*value_index].GetValue();
|
||||||
|
Handle<HeapNumber> box;
|
||||||
CHECK(value->IsNumber());
|
CHECK(value->IsNumber());
|
||||||
Handle<MutableHeapNumber> box =
|
box = isolate()->factory()->NewHeapNumber(value->Number(), MUTABLE);
|
||||||
isolate()->factory()->NewMutableHeapNumber(value->Number());
|
|
||||||
(*value_index)++;
|
(*value_index)++;
|
||||||
slot->set_storage(box);
|
slot->set_storage(box);
|
||||||
}
|
}
|
||||||
|
@ -117,37 +117,23 @@ Handle<Object> Factory::NewNumberFromInt64(int64_t value,
|
|||||||
return NewNumber(static_cast<double>(value), pretenure);
|
return NewNumber(static_cast<double>(value), pretenure);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<HeapNumber> Factory::NewHeapNumber(double value,
|
Handle<HeapNumber> Factory::NewHeapNumber(double value, MutableMode mode,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
Handle<HeapNumber> heap_number = NewHeapNumber(pretenure);
|
Handle<HeapNumber> heap_number = NewHeapNumber(mode, pretenure);
|
||||||
heap_number->set_value(value);
|
heap_number->set_value(value);
|
||||||
return heap_number;
|
return heap_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<MutableHeapNumber> Factory::NewMutableHeapNumber(
|
|
||||||
double value, PretenureFlag pretenure) {
|
|
||||||
Handle<MutableHeapNumber> number = NewMutableHeapNumber(pretenure);
|
|
||||||
number->set_value(value);
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<HeapNumber> Factory::NewHeapNumberFromBits(uint64_t bits,
|
Handle<HeapNumber> Factory::NewHeapNumberFromBits(uint64_t bits,
|
||||||
|
MutableMode mode,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
Handle<HeapNumber> heap_number = NewHeapNumber(pretenure);
|
Handle<HeapNumber> heap_number = NewHeapNumber(mode, pretenure);
|
||||||
heap_number->set_value_as_bits(bits);
|
heap_number->set_value_as_bits(bits);
|
||||||
return heap_number;
|
return heap_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<MutableHeapNumber> Factory::NewMutableHeapNumberFromBits(
|
Handle<HeapNumber> Factory::NewMutableHeapNumber(PretenureFlag pretenure) {
|
||||||
uint64_t bits, PretenureFlag pretenure) {
|
return NewHeapNumberFromBits(kHoleNanInt64, MUTABLE, pretenure);
|
||||||
Handle<MutableHeapNumber> number = NewMutableHeapNumber(pretenure);
|
|
||||||
number->set_value_as_bits(bits);
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<MutableHeapNumber> Factory::NewMutableHeapNumberWithHoleNaN(
|
|
||||||
PretenureFlag pretenure) {
|
|
||||||
return NewMutableHeapNumberFromBits(kHoleNanInt64, pretenure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
||||||
|
@ -2112,14 +2112,16 @@ Handle<Object> Factory::NewNumber(double value, PretenureFlag pretenure) {
|
|||||||
if (DoubleToSmiInteger(value, &int_value)) {
|
if (DoubleToSmiInteger(value, &int_value)) {
|
||||||
return handle(Smi::FromInt(int_value), isolate());
|
return handle(Smi::FromInt(int_value), isolate());
|
||||||
}
|
}
|
||||||
return NewHeapNumber(value, pretenure);
|
|
||||||
|
// Materialize the value in the heap.
|
||||||
|
return NewHeapNumber(value, IMMUTABLE, pretenure);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> Factory::NewNumberFromInt(int32_t value,
|
Handle<Object> Factory::NewNumberFromInt(int32_t value,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
|
if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
|
||||||
// Bypass NewNumber to avoid various redundant checks.
|
// Bypass NewNumber to avoid various redundant checks.
|
||||||
return NewHeapNumber(FastI2D(value), pretenure);
|
return NewHeapNumber(FastI2D(value), IMMUTABLE, pretenure);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> Factory::NewNumberFromUint(uint32_t value,
|
Handle<Object> Factory::NewNumberFromUint(uint32_t value,
|
||||||
@ -2128,26 +2130,18 @@ Handle<Object> Factory::NewNumberFromUint(uint32_t value,
|
|||||||
if (int32v >= 0 && Smi::IsValid(int32v)) {
|
if (int32v >= 0 && Smi::IsValid(int32v)) {
|
||||||
return handle(Smi::FromInt(int32v), isolate());
|
return handle(Smi::FromInt(int32v), isolate());
|
||||||
}
|
}
|
||||||
return NewHeapNumber(FastUI2D(value), pretenure);
|
return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<HeapNumber> Factory::NewHeapNumber(PretenureFlag pretenure) {
|
Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode,
|
||||||
|
PretenureFlag pretenure) {
|
||||||
STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
|
STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
|
||||||
Map* map = *heap_number_map();
|
Map* map = mode == MUTABLE ? *mutable_heap_number_map() : *heap_number_map();
|
||||||
HeapObject* result = AllocateRawWithImmortalMap(HeapNumber::kSize, pretenure,
|
HeapObject* result = AllocateRawWithImmortalMap(HeapNumber::kSize, pretenure,
|
||||||
map, kDoubleUnaligned);
|
map, kDoubleUnaligned);
|
||||||
return handle(HeapNumber::cast(result), isolate());
|
return handle(HeapNumber::cast(result), isolate());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<MutableHeapNumber> Factory::NewMutableHeapNumber(
|
|
||||||
PretenureFlag pretenure) {
|
|
||||||
STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
|
|
||||||
Map* map = *mutable_heap_number_map();
|
|
||||||
HeapObject* result = AllocateRawWithImmortalMap(
|
|
||||||
MutableHeapNumber::kSize, pretenure, map, kDoubleUnaligned);
|
|
||||||
return handle(MutableHeapNumber::cast(result), isolate());
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length,
|
Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
if (length < 0 || length > BigInt::kMaxLength) {
|
if (length < 0 || length > BigInt::kMaxLength) {
|
||||||
|
@ -527,21 +527,18 @@ class V8_EXPORT_PRIVATE Factory {
|
|||||||
inline Handle<Object> NewNumberFromInt64(
|
inline Handle<Object> NewNumberFromInt64(
|
||||||
int64_t value, PretenureFlag pretenure = NOT_TENURED);
|
int64_t value, PretenureFlag pretenure = NOT_TENURED);
|
||||||
inline Handle<HeapNumber> NewHeapNumber(
|
inline Handle<HeapNumber> NewHeapNumber(
|
||||||
double value, PretenureFlag pretenure = NOT_TENURED);
|
double value, MutableMode mode = IMMUTABLE,
|
||||||
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
inline Handle<HeapNumber> NewHeapNumberFromBits(
|
inline Handle<HeapNumber> NewHeapNumberFromBits(
|
||||||
uint64_t bits, PretenureFlag pretenure = NOT_TENURED);
|
uint64_t bits, MutableMode mode = IMMUTABLE,
|
||||||
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
|
// Creates mutable heap number object with value field set to hole NaN.
|
||||||
|
inline Handle<HeapNumber> NewMutableHeapNumber(
|
||||||
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
|
|
||||||
// Creates heap number object with not yet set value field.
|
// Creates heap number object with not yet set value field.
|
||||||
Handle<HeapNumber> NewHeapNumber(PretenureFlag pretenure = NOT_TENURED);
|
Handle<HeapNumber> NewHeapNumber(MutableMode mode,
|
||||||
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
Handle<MutableHeapNumber> NewMutableHeapNumber(
|
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
inline Handle<MutableHeapNumber> NewMutableHeapNumber(
|
|
||||||
double value, PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
inline Handle<MutableHeapNumber> NewMutableHeapNumberFromBits(
|
|
||||||
uint64_t bits, PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
inline Handle<MutableHeapNumber> NewMutableHeapNumberWithHoleNaN(
|
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
|
|
||||||
// Allocates a new BigInt with {length} digits. Only to be used by
|
// Allocates a new BigInt with {length} digits. Only to be used by
|
||||||
// MutableBigInt::New*.
|
// MutableBigInt::New*.
|
||||||
|
@ -368,7 +368,7 @@ bool Heap::CreateInitialMaps() {
|
|||||||
ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector)
|
ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector)
|
||||||
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
||||||
Context::NUMBER_FUNCTION_INDEX)
|
Context::NUMBER_FUNCTION_INDEX)
|
||||||
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, MutableHeapNumber::kSize,
|
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
|
||||||
mutable_heap_number)
|
mutable_heap_number)
|
||||||
ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
|
ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
|
||||||
Context::SYMBOL_FUNCTION_INDEX)
|
Context::SYMBOL_FUNCTION_INDEX)
|
||||||
@ -586,16 +586,18 @@ void Heap::CreateInitialObjects() {
|
|||||||
Factory* factory = isolate()->factory();
|
Factory* factory = isolate()->factory();
|
||||||
|
|
||||||
// The -0 value must be set before NewNumber works.
|
// The -0 value must be set before NewNumber works.
|
||||||
set_minus_zero_value(*factory->NewHeapNumber(-0.0, TENURED_READ_ONLY));
|
set_minus_zero_value(
|
||||||
|
*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED_READ_ONLY));
|
||||||
DCHECK(std::signbit(minus_zero_value()->Number()));
|
DCHECK(std::signbit(minus_zero_value()->Number()));
|
||||||
|
|
||||||
set_nan_value(*factory->NewHeapNumber(
|
set_nan_value(*factory->NewHeapNumber(
|
||||||
std::numeric_limits<double>::quiet_NaN(), TENURED_READ_ONLY));
|
std::numeric_limits<double>::quiet_NaN(), IMMUTABLE, TENURED_READ_ONLY));
|
||||||
set_hole_nan_value(
|
set_hole_nan_value(*factory->NewHeapNumberFromBits(kHoleNanInt64, IMMUTABLE,
|
||||||
*factory->NewHeapNumberFromBits(kHoleNanInt64, TENURED_READ_ONLY));
|
TENURED_READ_ONLY));
|
||||||
set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, TENURED_READ_ONLY));
|
set_infinity_value(
|
||||||
|
*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED_READ_ONLY));
|
||||||
set_minus_infinity_value(
|
set_minus_infinity_value(
|
||||||
*factory->NewHeapNumber(-V8_INFINITY, TENURED_READ_ONLY));
|
*factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED_READ_ONLY));
|
||||||
|
|
||||||
// Allocate cache for single character one byte strings.
|
// Allocate cache for single character one byte strings.
|
||||||
set_single_character_string_cache(
|
set_single_character_string_cache(
|
||||||
|
@ -303,8 +303,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Handle<HeapObject> object;
|
Handle<HeapObject> object;
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
break;
|
break;
|
||||||
case HeapObjectRequest::kCodeStub:
|
case HeapObjectRequest::kCodeStub:
|
||||||
request.code_stub()->set_isolate(isolate);
|
request.code_stub()->set_isolate(isolate);
|
||||||
|
@ -1091,7 +1091,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
|
|||||||
} else {
|
} else {
|
||||||
if (do_transitioning_store) {
|
if (do_transitioning_store) {
|
||||||
Node* mutable_heap_number =
|
Node* mutable_heap_number =
|
||||||
AllocateMutableHeapNumberWithValue(double_value);
|
AllocateHeapNumberWithValue(double_value, MUTABLE);
|
||||||
StoreMap(object, object_map);
|
StoreMap(object, object_map);
|
||||||
StoreObjectField(object, field_offset, mutable_heap_number);
|
StoreObjectField(object, field_offset, mutable_heap_number);
|
||||||
} else {
|
} else {
|
||||||
@ -1130,7 +1130,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
|
|||||||
{
|
{
|
||||||
Node* double_value = ChangeNumberToFloat64(value);
|
Node* double_value = ChangeNumberToFloat64(value);
|
||||||
Node* mutable_heap_number =
|
Node* mutable_heap_number =
|
||||||
AllocateMutableHeapNumberWithValue(double_value);
|
AllocateHeapNumberWithValue(double_value, MUTABLE);
|
||||||
var_value.Bind(mutable_heap_number);
|
var_value.Bind(mutable_heap_number);
|
||||||
Goto(&cont);
|
Goto(&cont);
|
||||||
}
|
}
|
||||||
|
@ -262,8 +262,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Handle<HeapObject> object;
|
Handle<HeapObject> object;
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
break;
|
break;
|
||||||
case HeapObjectRequest::kCodeStub:
|
case HeapObjectRequest::kCodeStub:
|
||||||
request.code_stub()->set_isolate(isolate);
|
request.code_stub()->set_isolate(isolate);
|
||||||
|
@ -241,8 +241,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Handle<HeapObject> object;
|
Handle<HeapObject> object;
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
break;
|
break;
|
||||||
case HeapObjectRequest::kCodeStub:
|
case HeapObjectRequest::kCodeStub:
|
||||||
request.code_stub()->set_isolate(isolate);
|
request.code_stub()->set_isolate(isolate);
|
||||||
|
@ -110,8 +110,10 @@ void Smi::SmiVerify(Isolate* isolate) {
|
|||||||
void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||||
VerifyHeapPointer(map());
|
VerifyHeapPointer(map());
|
||||||
CHECK(map()->IsMap());
|
CHECK(map()->IsMap());
|
||||||
|
InstanceType instance_type = map()->instance_type();
|
||||||
|
|
||||||
switch (map()->instance_type()) {
|
|
||||||
|
switch (instance_type) {
|
||||||
#define STRING_TYPE_CASE(TYPE, size, name, camel_name) case TYPE:
|
#define STRING_TYPE_CASE(TYPE, size, name, camel_name) case TYPE:
|
||||||
STRING_TYPE_LIST(STRING_TYPE_CASE)
|
STRING_TYPE_LIST(STRING_TYPE_CASE)
|
||||||
#undef STRING_TYPE_CASE
|
#undef STRING_TYPE_CASE
|
||||||
@ -124,10 +126,8 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
|||||||
Map::cast(this)->MapVerify(isolate);
|
Map::cast(this)->MapVerify(isolate);
|
||||||
break;
|
break;
|
||||||
case HEAP_NUMBER_TYPE:
|
case HEAP_NUMBER_TYPE:
|
||||||
CHECK(IsHeapNumber());
|
|
||||||
break;
|
|
||||||
case MUTABLE_HEAP_NUMBER_TYPE:
|
case MUTABLE_HEAP_NUMBER_TYPE:
|
||||||
CHECK(IsMutableHeapNumber());
|
HeapNumber::cast(this)->HeapNumberVerify(isolate);
|
||||||
break;
|
break;
|
||||||
case BIGINT_TYPE:
|
case BIGINT_TYPE:
|
||||||
BigInt::cast(this)->BigIntVerify(isolate);
|
BigInt::cast(this)->BigIntVerify(isolate);
|
||||||
@ -372,6 +372,10 @@ void Symbol::SymbolVerify(Isolate* isolate) {
|
|||||||
CHECK_IMPLIES(IsPrivateField(), IsPrivate());
|
CHECK_IMPLIES(IsPrivateField(), IsPrivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HeapNumber::HeapNumberVerify(Isolate* isolate) {
|
||||||
|
CHECK(IsHeapNumber() || IsMutableHeapNumber());
|
||||||
|
}
|
||||||
|
|
||||||
void ByteArray::ByteArrayVerify(Isolate* isolate) { CHECK(IsByteArray()); }
|
void ByteArray::ByteArrayVerify(Isolate* isolate) { CHECK(IsByteArray()); }
|
||||||
|
|
||||||
void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
|
void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
|
||||||
|
@ -640,9 +640,7 @@ CAST_ACCESSOR(JSProxy)
|
|||||||
CAST_ACCESSOR(JSReceiver)
|
CAST_ACCESSOR(JSReceiver)
|
||||||
CAST_ACCESSOR(JSStringIterator)
|
CAST_ACCESSOR(JSStringIterator)
|
||||||
CAST_ACCESSOR(JSValue)
|
CAST_ACCESSOR(JSValue)
|
||||||
CAST_ACCESSOR(HeapNumber)
|
|
||||||
CAST_ACCESSOR(LayoutDescriptor)
|
CAST_ACCESSOR(LayoutDescriptor)
|
||||||
CAST_ACCESSOR(MutableHeapNumber)
|
|
||||||
CAST_ACCESSOR(NameDictionary)
|
CAST_ACCESSOR(NameDictionary)
|
||||||
CAST_ACCESSOR(NormalizedMapCache)
|
CAST_ACCESSOR(NormalizedMapCache)
|
||||||
CAST_ACCESSOR(NumberDictionary)
|
CAST_ACCESSOR(NumberDictionary)
|
||||||
@ -707,13 +705,12 @@ bool Object::FilterKey(PropertyFilter filter) {
|
|||||||
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
|
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
|
||||||
Representation representation) {
|
Representation representation) {
|
||||||
if (!representation.IsDouble()) return object;
|
if (!representation.IsDouble()) return object;
|
||||||
auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
Handle<HeapNumber> result = isolate->factory()->NewHeapNumber(MUTABLE);
|
||||||
if (object->IsUninitialized(isolate)) {
|
if (object->IsUninitialized(isolate)) {
|
||||||
result->set_value_as_bits(kHoleNanInt64);
|
result->set_value_as_bits(kHoleNanInt64);
|
||||||
} else if (object->IsMutableHeapNumber()) {
|
} else if (object->IsMutableHeapNumber()) {
|
||||||
// Ensure that all bits of the double value are preserved.
|
// Ensure that all bits of the double value are preserved.
|
||||||
result->set_value_as_bits(
|
result->set_value_as_bits(HeapNumber::cast(*object)->value_as_bits());
|
||||||
MutableHeapNumber::cast(*object)->value_as_bits());
|
|
||||||
} else {
|
} else {
|
||||||
result->set_value(object->Number());
|
result->set_value(object->Number());
|
||||||
}
|
}
|
||||||
@ -727,8 +724,7 @@ Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
|
|||||||
DCHECK(object->FitsRepresentation(representation));
|
DCHECK(object->FitsRepresentation(representation));
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
return isolate->factory()->NewHeapNumber(
|
return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value());
|
||||||
MutableHeapNumber::cast(*object)->value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Representation Object::OptimalRepresentation() {
|
Representation Object::OptimalRepresentation() {
|
||||||
@ -1122,28 +1118,30 @@ void HeapObject::synchronized_set_map_word(MapWord map_word) {
|
|||||||
|
|
||||||
int HeapObject::Size() const { return SizeFromMap(map()); }
|
int HeapObject::Size() const { return SizeFromMap(map()); }
|
||||||
|
|
||||||
double HeapNumberBase::value() const {
|
double HeapNumber::value() const {
|
||||||
return READ_DOUBLE_FIELD(this, kValueOffset);
|
return READ_DOUBLE_FIELD(this, kValueOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeapNumberBase::set_value(double value) {
|
|
||||||
|
void HeapNumber::set_value(double value) {
|
||||||
WRITE_DOUBLE_FIELD(this, kValueOffset, value);
|
WRITE_DOUBLE_FIELD(this, kValueOffset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t HeapNumberBase::value_as_bits() const {
|
uint64_t HeapNumber::value_as_bits() const {
|
||||||
return READ_UINT64_FIELD(this, kValueOffset);
|
return READ_UINT64_FIELD(this, kValueOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeapNumberBase::set_value_as_bits(uint64_t bits) {
|
void HeapNumber::set_value_as_bits(uint64_t bits) {
|
||||||
WRITE_UINT64_FIELD(this, kValueOffset, bits);
|
WRITE_UINT64_FIELD(this, kValueOffset, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
int HeapNumberBase::get_exponent() {
|
int HeapNumber::get_exponent() {
|
||||||
return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
|
return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
|
||||||
kExponentShift) - kExponentBias;
|
kExponentShift) - kExponentBias;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HeapNumberBase::get_sign() {
|
|
||||||
|
int HeapNumber::get_sign() {
|
||||||
return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
|
return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1626,8 +1624,8 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
|
|||||||
if (IsUnboxedDoubleField(index)) {
|
if (IsUnboxedDoubleField(index)) {
|
||||||
DCHECK(value->IsMutableHeapNumber());
|
DCHECK(value->IsMutableHeapNumber());
|
||||||
// Ensure that all bits of the double value are preserved.
|
// Ensure that all bits of the double value are preserved.
|
||||||
RawFastDoublePropertyAsBitsAtPut(
|
RawFastDoublePropertyAsBitsAtPut(index,
|
||||||
index, MutableHeapNumber::cast(value)->value_as_bits());
|
HeapNumber::cast(value)->value_as_bits());
|
||||||
} else {
|
} else {
|
||||||
RawFastPropertyAtPut(index, value);
|
RawFastPropertyAtPut(index, value);
|
||||||
}
|
}
|
||||||
@ -1658,7 +1656,8 @@ void JSObject::WriteToField(int descriptor, PropertyDetails details,
|
|||||||
if (IsUnboxedDoubleField(index)) {
|
if (IsUnboxedDoubleField(index)) {
|
||||||
RawFastDoublePropertyAsBitsAtPut(index, bits);
|
RawFastDoublePropertyAsBitsAtPut(index, bits);
|
||||||
} else {
|
} else {
|
||||||
auto box = MutableHeapNumber::cast(RawFastPropertyAt(index));
|
HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
|
||||||
|
DCHECK(box->IsMutableHeapNumber());
|
||||||
box->set_value_as_bits(bits);
|
box->set_value_as_bits(bits);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2731,6 +2730,18 @@ SMI_ACCESSORS(JSAsyncGeneratorObject, is_awaiting, kIsAwaitingOffset)
|
|||||||
ACCESSORS(JSValue, value, Object, kValueOffset)
|
ACCESSORS(JSValue, value, Object, kValueOffset)
|
||||||
|
|
||||||
|
|
||||||
|
HeapNumber* HeapNumber::cast(Object* object) {
|
||||||
|
SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
|
||||||
|
return reinterpret_cast<HeapNumber*>(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const HeapNumber* HeapNumber::cast(const Object* object) {
|
||||||
|
SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
|
||||||
|
return reinterpret_cast<const HeapNumber*>(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ACCESSORS(JSDate, value, Object, kValueOffset)
|
ACCESSORS(JSDate, value, Object, kValueOffset)
|
||||||
ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
|
ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
|
||||||
ACCESSORS(JSDate, year, Object, kYearOffset)
|
ACCESSORS(JSDate, year, Object, kYearOffset)
|
||||||
|
@ -89,7 +89,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
|||||||
break;
|
break;
|
||||||
case MUTABLE_HEAP_NUMBER_TYPE:
|
case MUTABLE_HEAP_NUMBER_TYPE:
|
||||||
os << "<mutable ";
|
os << "<mutable ";
|
||||||
MutableHeapNumber::cast(this)->MutableHeapNumberPrint(os);
|
HeapNumber::cast(this)->HeapNumberPrint(os);
|
||||||
os << ">\n";
|
os << ">\n";
|
||||||
break;
|
break;
|
||||||
case BIGINT_TYPE:
|
case BIGINT_TYPE:
|
||||||
@ -2144,12 +2144,6 @@ void MaybeObject::Print(std::ostream& os) {
|
|||||||
|
|
||||||
#endif // OBJECT_PRINT
|
#endif // OBJECT_PRINT
|
||||||
|
|
||||||
void HeapNumber::HeapNumberPrint(std::ostream& os) { os << value(); }
|
|
||||||
|
|
||||||
void MutableHeapNumber::MutableHeapNumberPrint(std::ostream& os) {
|
|
||||||
os << value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(cbruni): remove once the new maptracer is in place.
|
// TODO(cbruni): remove once the new maptracer is in place.
|
||||||
void Name::NameShortPrint() {
|
void Name::NameShortPrint() {
|
||||||
if (this->IsString()) {
|
if (this->IsString()) {
|
||||||
|
@ -3449,14 +3449,14 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HEAP_NUMBER_TYPE: {
|
case HEAP_NUMBER_TYPE: {
|
||||||
os << "<HeapNumber ";
|
os << "<Number ";
|
||||||
HeapNumber::cast(this)->HeapNumberPrint(os);
|
HeapNumber::cast(this)->HeapNumberPrint(os);
|
||||||
os << ">";
|
os << ">";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MUTABLE_HEAP_NUMBER_TYPE: {
|
case MUTABLE_HEAP_NUMBER_TYPE: {
|
||||||
os << "<MutableHeapNumber ";
|
os << "<MutableNumber ";
|
||||||
MutableHeapNumber::cast(this)->MutableHeapNumberPrint(os);
|
HeapNumber::cast(this)->HeapNumberPrint(os);
|
||||||
os << '>';
|
os << '>';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3562,6 +3562,10 @@ bool HeapObject::IsValidSlot(Map* map, int offset) {
|
|||||||
this, offset, 0);
|
this, offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HeapNumber::HeapNumberPrint(std::ostream& os) { // NOLINT
|
||||||
|
os << value();
|
||||||
|
}
|
||||||
|
|
||||||
String* JSReceiver::class_name() {
|
String* JSReceiver::class_name() {
|
||||||
if (IsFunction()) return GetHeap()->Function_string();
|
if (IsFunction()) return GetHeap()->Function_string();
|
||||||
if (IsJSArgumentsObject()) return GetHeap()->Arguments_string();
|
if (IsJSArgumentsObject()) return GetHeap()->Arguments_string();
|
||||||
@ -3999,7 +4003,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
|
FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
|
||||||
DCHECK(details.representation().IsDouble());
|
DCHECK(details.representation().IsDouble());
|
||||||
DCHECK(!new_map->IsUnboxedDoubleField(index));
|
DCHECK(!new_map->IsUnboxedDoubleField(index));
|
||||||
auto value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
Handle<Object> value = isolate->factory()->NewMutableHeapNumber();
|
||||||
object->RawFastPropertyAtPut(index, *value);
|
object->RawFastPropertyAtPut(index, *value);
|
||||||
object->synchronized_set_map(*new_map);
|
object->synchronized_set_map(*new_map);
|
||||||
return;
|
return;
|
||||||
@ -4015,7 +4019,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
// Properly initialize newly added property.
|
// Properly initialize newly added property.
|
||||||
Handle<Object> value;
|
Handle<Object> value;
|
||||||
if (details.representation().IsDouble()) {
|
if (details.representation().IsDouble()) {
|
||||||
value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
value = isolate->factory()->NewMutableHeapNumber();
|
||||||
} else {
|
} else {
|
||||||
value = isolate->factory()->uninitialized_value();
|
value = isolate->factory()->uninitialized_value();
|
||||||
}
|
}
|
||||||
@ -4079,7 +4083,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
// must already be prepared for data of certain type.
|
// must already be prepared for data of certain type.
|
||||||
DCHECK(!details.representation().IsNone());
|
DCHECK(!details.representation().IsNone());
|
||||||
if (details.representation().IsDouble()) {
|
if (details.representation().IsDouble()) {
|
||||||
value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
value = isolate->factory()->NewMutableHeapNumber();
|
||||||
} else {
|
} else {
|
||||||
value = isolate->factory()->uninitialized_value();
|
value = isolate->factory()->uninitialized_value();
|
||||||
}
|
}
|
||||||
@ -4093,11 +4097,9 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
|
FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
|
||||||
if (object->IsUnboxedDoubleField(index)) {
|
if (object->IsUnboxedDoubleField(index)) {
|
||||||
uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
|
uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
|
||||||
if (representation.IsDouble()) {
|
value = isolate->factory()->NewHeapNumberFromBits(
|
||||||
value = isolate->factory()->NewMutableHeapNumberFromBits(old_bits);
|
old_bits, representation.IsDouble() ? MUTABLE : IMMUTABLE);
|
||||||
} else {
|
|
||||||
value = isolate->factory()->NewHeapNumberFromBits(old_bits);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
value = handle(object->RawFastPropertyAt(index), isolate);
|
value = handle(object->RawFastPropertyAt(index), isolate);
|
||||||
if (!old_representation.IsDouble() && representation.IsDouble()) {
|
if (!old_representation.IsDouble() && representation.IsDouble()) {
|
||||||
@ -4125,7 +4127,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
DCHECK_EQ(kData, details.kind());
|
DCHECK_EQ(kData, details.kind());
|
||||||
Handle<Object> value;
|
Handle<Object> value;
|
||||||
if (details.representation().IsDouble()) {
|
if (details.representation().IsDouble()) {
|
||||||
value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
value = isolate->factory()->NewMutableHeapNumber();
|
||||||
} else {
|
} else {
|
||||||
value = isolate->factory()->uninitialized_value();
|
value = isolate->factory()->uninitialized_value();
|
||||||
}
|
}
|
||||||
@ -4158,7 +4160,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
|||||||
DCHECK(value->IsMutableHeapNumber());
|
DCHECK(value->IsMutableHeapNumber());
|
||||||
// Ensure that all bits of the double value are preserved.
|
// Ensure that all bits of the double value are preserved.
|
||||||
object->RawFastDoublePropertyAsBitsAtPut(
|
object->RawFastDoublePropertyAsBitsAtPut(
|
||||||
index, MutableHeapNumber::cast(value)->value_as_bits());
|
index, HeapNumber::cast(value)->value_as_bits());
|
||||||
if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
|
if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
|
||||||
// Transition from tagged to untagged slot.
|
// Transition from tagged to untagged slot.
|
||||||
heap->ClearRecordedSlot(*object,
|
heap->ClearRecordedSlot(*object,
|
||||||
@ -4231,8 +4233,8 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
|
|||||||
value = handle(object->RawFastPropertyAt(index), isolate);
|
value = handle(object->RawFastPropertyAt(index), isolate);
|
||||||
if (details.representation().IsDouble()) {
|
if (details.representation().IsDouble()) {
|
||||||
DCHECK(value->IsMutableHeapNumber());
|
DCHECK(value->IsMutableHeapNumber());
|
||||||
double old_value = Handle<MutableHeapNumber>::cast(value)->value();
|
Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
|
||||||
value = isolate->factory()->NewHeapNumber(old_value);
|
value = isolate->factory()->NewHeapNumber(old->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -5974,7 +5976,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
|
|||||||
if (!representation.IsDouble()) continue;
|
if (!representation.IsDouble()) continue;
|
||||||
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
|
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
|
||||||
if (map->IsUnboxedDoubleField(index)) continue;
|
if (map->IsUnboxedDoubleField(index)) continue;
|
||||||
auto box = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
Handle<HeapNumber> box = isolate->factory()->NewMutableHeapNumber();
|
||||||
if (index.is_inobject()) {
|
if (index.is_inobject()) {
|
||||||
storage->set(index.property_index(), *box);
|
storage->set(index.property_index(), *box);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1981,11 +1981,10 @@ class FixedBodyDescriptor;
|
|||||||
template <int start_offset>
|
template <int start_offset>
|
||||||
class FlexibleBodyDescriptor;
|
class FlexibleBodyDescriptor;
|
||||||
|
|
||||||
|
|
||||||
// The HeapNumber class describes heap allocated numbers that cannot be
|
// The HeapNumber class describes heap allocated numbers that cannot be
|
||||||
// represented in a Smi (small integer). MutableHeapNumber is the same, but its
|
// represented in a Smi (small integer)
|
||||||
// number value can change over time (it is used only as property storage).
|
class HeapNumber: public HeapObject {
|
||||||
// HeapNumberBase merely exists to avoid code duplication.
|
|
||||||
class HeapNumberBase : public HeapObject {
|
|
||||||
public:
|
public:
|
||||||
// [value]: number value.
|
// [value]: number value.
|
||||||
inline double value() const;
|
inline double value() const;
|
||||||
@ -1994,6 +1993,11 @@ class HeapNumberBase : public HeapObject {
|
|||||||
inline uint64_t value_as_bits() const;
|
inline uint64_t value_as_bits() const;
|
||||||
inline void set_value_as_bits(uint64_t bits);
|
inline void set_value_as_bits(uint64_t bits);
|
||||||
|
|
||||||
|
DECL_CAST(HeapNumber)
|
||||||
|
|
||||||
|
V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os); // NOLINT
|
||||||
|
DECL_VERIFIER(HeapNumber)
|
||||||
|
|
||||||
inline int get_exponent();
|
inline int get_exponent();
|
||||||
inline int get_sign();
|
inline int get_sign();
|
||||||
|
|
||||||
@ -2027,25 +2031,7 @@ class HeapNumberBase : public HeapObject {
|
|||||||
static const int kNonMantissaBitsInTopWord = 12;
|
static const int kNonMantissaBitsInTopWord = 12;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumberBase)
|
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
|
||||||
};
|
|
||||||
|
|
||||||
class HeapNumber : public HeapNumberBase {
|
|
||||||
public:
|
|
||||||
DECL_CAST(HeapNumber)
|
|
||||||
V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os);
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber)
|
|
||||||
};
|
|
||||||
|
|
||||||
class MutableHeapNumber : public HeapNumberBase {
|
|
||||||
public:
|
|
||||||
DECL_CAST(MutableHeapNumber)
|
|
||||||
V8_EXPORT_PRIVATE void MutableHeapNumberPrint(std::ostream& os);
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(MutableHeapNumber)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EnsureElementsMode {
|
enum EnsureElementsMode {
|
||||||
|
@ -222,8 +222,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Handle<HeapObject> object;
|
Handle<HeapObject> object;
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
break;
|
break;
|
||||||
case HeapObjectRequest::kCodeStub:
|
case HeapObjectRequest::kCodeStub:
|
||||||
request.code_stub()->set_isolate(isolate);
|
request.code_stub()->set_isolate(isolate);
|
||||||
|
@ -122,9 +122,9 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
|||||||
if (copying) copy->FastPropertyAtPut(index, *value);
|
if (copying) copy->FastPropertyAtPut(index, *value);
|
||||||
} else if (copying && raw->IsMutableHeapNumber()) {
|
} else if (copying && raw->IsMutableHeapNumber()) {
|
||||||
DCHECK(descriptors->GetDetails(i).representation().IsDouble());
|
DCHECK(descriptors->GetDetails(i).representation().IsDouble());
|
||||||
uint64_t double_value = MutableHeapNumber::cast(raw)->value_as_bits();
|
uint64_t double_value = HeapNumber::cast(raw)->value_as_bits();
|
||||||
auto value =
|
Handle<HeapNumber> value = isolate->factory()->NewHeapNumber(MUTABLE);
|
||||||
isolate->factory()->NewMutableHeapNumberFromBits(double_value);
|
value->set_value_as_bits(double_value);
|
||||||
copy->FastPropertyAtPut(index, *value);
|
copy->FastPropertyAtPut(index, *value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,8 +327,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Address pc = reinterpret_cast<Address>(buffer_ + request.offset());
|
Address pc = reinterpret_cast<Address>(buffer_ + request.offset());
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber:
|
case HeapObjectRequest::kHeapNumber:
|
||||||
object =
|
object = isolate->factory()->NewHeapNumber(request.heap_number(),
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
IMMUTABLE, TENURED);
|
||||||
set_target_address_at(pc, kNullAddress,
|
set_target_address_at(pc, kNullAddress,
|
||||||
reinterpret_cast<Address>(object.location()),
|
reinterpret_cast<Address>(object.location()),
|
||||||
SKIP_ICACHE_FLUSH);
|
SKIP_ICACHE_FLUSH);
|
||||||
|
@ -356,10 +356,8 @@ Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
|
|||||||
WriteOddball(Oddball::cast(*object));
|
WriteOddball(Oddball::cast(*object));
|
||||||
return ThrowIfOutOfMemory();
|
return ThrowIfOutOfMemory();
|
||||||
case HEAP_NUMBER_TYPE:
|
case HEAP_NUMBER_TYPE:
|
||||||
WriteHeapNumber(HeapNumber::cast(*object));
|
|
||||||
return ThrowIfOutOfMemory();
|
|
||||||
case MUTABLE_HEAP_NUMBER_TYPE:
|
case MUTABLE_HEAP_NUMBER_TYPE:
|
||||||
WriteMutableHeapNumber(MutableHeapNumber::cast(*object));
|
WriteHeapNumber(HeapNumber::cast(*object));
|
||||||
return ThrowIfOutOfMemory();
|
return ThrowIfOutOfMemory();
|
||||||
case BIGINT_TYPE:
|
case BIGINT_TYPE:
|
||||||
WriteBigInt(BigInt::cast(*object));
|
WriteBigInt(BigInt::cast(*object));
|
||||||
@ -427,11 +425,6 @@ void ValueSerializer::WriteHeapNumber(HeapNumber* number) {
|
|||||||
WriteDouble(number->value());
|
WriteDouble(number->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValueSerializer::WriteMutableHeapNumber(MutableHeapNumber* number) {
|
|
||||||
WriteTag(SerializationTag::kDouble);
|
|
||||||
WriteDouble(number->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueSerializer::WriteBigInt(BigInt* bigint) {
|
void ValueSerializer::WriteBigInt(BigInt* bigint) {
|
||||||
WriteTag(SerializationTag::kBigInt);
|
WriteTag(SerializationTag::kBigInt);
|
||||||
WriteBigIntContents(bigint);
|
WriteBigIntContents(bigint);
|
||||||
|
@ -29,7 +29,6 @@ class JSMap;
|
|||||||
class JSRegExp;
|
class JSRegExp;
|
||||||
class JSSet;
|
class JSSet;
|
||||||
class JSValue;
|
class JSValue;
|
||||||
class MutableHeapNumber;
|
|
||||||
class Object;
|
class Object;
|
||||||
class Oddball;
|
class Oddball;
|
||||||
class Smi;
|
class Smi;
|
||||||
@ -116,7 +115,6 @@ class ValueSerializer {
|
|||||||
void WriteOddball(Oddball* oddball);
|
void WriteOddball(Oddball* oddball);
|
||||||
void WriteSmi(Smi* smi);
|
void WriteSmi(Smi* smi);
|
||||||
void WriteHeapNumber(HeapNumber* number);
|
void WriteHeapNumber(HeapNumber* number);
|
||||||
void WriteMutableHeapNumber(MutableHeapNumber* number);
|
|
||||||
void WriteBigInt(BigInt* bigint);
|
void WriteBigInt(BigInt* bigint);
|
||||||
void WriteString(Handle<String> string);
|
void WriteString(Handle<String> string);
|
||||||
Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver)
|
Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver)
|
||||||
|
@ -339,8 +339,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
|||||||
Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
|
Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
|
||||||
switch (request.kind()) {
|
switch (request.kind()) {
|
||||||
case HeapObjectRequest::kHeapNumber: {
|
case HeapObjectRequest::kHeapNumber: {
|
||||||
Handle<HeapNumber> object =
|
Handle<HeapNumber> object = isolate->factory()->NewHeapNumber(
|
||||||
isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
|
request.heap_number(), IMMUTABLE, TENURED);
|
||||||
Memory::Object_Handle_at(pc) = object;
|
Memory::Object_Handle_at(pc) = object;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3293,7 +3293,7 @@ TEST(jump_tables3) {
|
|||||||
Handle<Object> values[kNumCases];
|
Handle<Object> values[kNumCases];
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kNumCases; ++i) {
|
||||||
double value = isolate->random_number_generator()->NextDouble();
|
double value = isolate->random_number_generator()->NextDouble();
|
||||||
values[i] = isolate->factory()->NewHeapNumber(value, TENURED);
|
values[i] = isolate->factory()->NewHeapNumber(value, IMMUTABLE, TENURED);
|
||||||
}
|
}
|
||||||
Label labels[kNumCases];
|
Label labels[kNumCases];
|
||||||
Object* obj;
|
Object* obj;
|
||||||
|
@ -3423,7 +3423,7 @@ TEST(jump_tables3) {
|
|||||||
Handle<Object> values[kNumCases];
|
Handle<Object> values[kNumCases];
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kNumCases; ++i) {
|
||||||
double value = isolate->random_number_generator()->NextDouble();
|
double value = isolate->random_number_generator()->NextDouble();
|
||||||
values[i] = isolate->factory()->NewHeapNumber(value, TENURED);
|
values[i] = isolate->factory()->NewHeapNumber(value, IMMUTABLE, TENURED);
|
||||||
}
|
}
|
||||||
Label labels[kNumCases];
|
Label labels[kNumCases];
|
||||||
Object* obj;
|
Object* obj;
|
||||||
|
@ -2777,10 +2777,10 @@ TEST(HoleyMutableHeapNumber) {
|
|||||||
v8::HandleScope scope(CcTest::isolate());
|
v8::HandleScope scope(CcTest::isolate());
|
||||||
Isolate* isolate = CcTest::i_isolate();
|
Isolate* isolate = CcTest::i_isolate();
|
||||||
|
|
||||||
auto mhn = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
|
Handle<HeapNumber> mhn = isolate->factory()->NewMutableHeapNumber();
|
||||||
CHECK_EQ(kHoleNanInt64, mhn->value_as_bits());
|
CHECK_EQ(kHoleNanInt64, mhn->value_as_bits());
|
||||||
|
|
||||||
mhn = isolate->factory()->NewMutableHeapNumber(0.0);
|
mhn = isolate->factory()->NewHeapNumber(0.0, MUTABLE);
|
||||||
CHECK_EQ(uint64_t{0}, mhn->value_as_bits());
|
CHECK_EQ(uint64_t{0}, mhn->value_as_bits());
|
||||||
|
|
||||||
mhn->set_value_as_bits(kHoleNanInt64);
|
mhn->set_value_as_bits(kHoleNanInt64);
|
||||||
@ -2793,11 +2793,11 @@ TEST(HoleyMutableHeapNumber) {
|
|||||||
Object::NewStorageFor(isolate, isolate->factory()->uninitialized_value(),
|
Object::NewStorageFor(isolate, isolate->factory()->uninitialized_value(),
|
||||||
Representation::Double());
|
Representation::Double());
|
||||||
CHECK(obj->IsMutableHeapNumber());
|
CHECK(obj->IsMutableHeapNumber());
|
||||||
CHECK_EQ(kHoleNanInt64, MutableHeapNumber::cast(*obj)->value_as_bits());
|
CHECK_EQ(kHoleNanInt64, HeapNumber::cast(*obj)->value_as_bits());
|
||||||
|
|
||||||
obj = Object::NewStorageFor(isolate, mhn, Representation::Double());
|
obj = Object::NewStorageFor(isolate, mhn, Representation::Double());
|
||||||
CHECK(obj->IsMutableHeapNumber());
|
CHECK(obj->IsMutableHeapNumber());
|
||||||
CHECK_EQ(kHoleNanInt64, MutableHeapNumber::cast(*obj)->value_as_bits());
|
CHECK_EQ(kHoleNanInt64, HeapNumber::cast(*obj)->value_as_bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace test_field_type_tracking
|
} // namespace test_field_type_tracking
|
||||||
|
@ -1100,7 +1100,7 @@ TEST(DoScavenge) {
|
|||||||
double boom_value = bit_cast<double>(fake_object);
|
double boom_value = bit_cast<double>(fake_object);
|
||||||
|
|
||||||
FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
|
FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
|
||||||
auto boom_number = factory->NewMutableHeapNumber(boom_value);
|
Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE);
|
||||||
obj->FastPropertyAtPut(field_index, *boom_number);
|
obj->FastPropertyAtPut(field_index, *boom_number);
|
||||||
|
|
||||||
// Now |obj| moves to old gen and it has a double field that looks like
|
// Now |obj| moves to old gen and it has a double field that looks like
|
||||||
|
Loading…
Reference in New Issue
Block a user