diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index 691f7ac346..1f82a24c32 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -477,8 +477,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); break; case HeapObjectRequest::kCodeStub: request.code_stub()->set_isolate(isolate); diff --git a/src/arm64/assembler-arm64.cc b/src/arm64/assembler-arm64.cc index e5287e16dd..49376762a6 100644 --- a/src/arm64/assembler-arm64.cc +++ b/src/arm64/assembler-arm64.cc @@ -591,8 +591,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast
(buffer_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - Handle object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + Handle object = isolate->factory()->NewHeapNumber( + request.heap_number(), IMMUTABLE, TENURED); set_target_address_at(pc, 0 /* unused */, object.address()); break; } diff --git a/src/builtins/builtins-constructor-gen.cc b/src/builtins/builtins-constructor-gen.cc index 9573168cf6..0071e1bcf4 100644 --- a/src/builtins/builtins-constructor-gen.cc +++ b/src/builtins/builtins-constructor-gen.cc @@ -577,7 +577,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( { Node* double_value = LoadHeapNumberValue(field); Node* mutable_heap_number = - AllocateMutableHeapNumberWithValue(double_value); + AllocateHeapNumberWithValue(double_value, MUTABLE); StoreObjectField(copy, offset, mutable_heap_number); Goto(&continue_loop); } diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index 59217c6d6c..560d1da271 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -2439,12 +2439,6 @@ void CodeStubAssembler::StoreHeapNumberValue(SloppyTNode object, MachineRepresentation::kFloat64); } -void CodeStubAssembler::StoreMutableHeapNumberValue( - SloppyTNode object, SloppyTNode value) { - StoreObjectFieldNoWriteBarrier(object, MutableHeapNumber::kValueOffset, value, - MachineRepresentation::kFloat64); -} - Node* CodeStubAssembler::StoreObjectField( Node* object, int offset, Node* value) { DCHECK_NE(HeapObject::kMapOffset, offset); // Use StoreMap instead. @@ -2783,34 +2777,22 @@ Node* CodeStubAssembler::StoreCellValue(Node* cell, Node* value, } } -TNode CodeStubAssembler::AllocateHeapNumber() { +TNode CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { 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); return UncheckedCast(result); } TNode CodeStubAssembler::AllocateHeapNumberWithValue( - SloppyTNode value) { - TNode result = AllocateHeapNumber(); + SloppyTNode value, MutableMode mode) { + TNode result = AllocateHeapNumber(mode); StoreHeapNumberValue(result, value); return result; } -TNode CodeStubAssembler::AllocateMutableHeapNumber() { - Node* result = Allocate(MutableHeapNumber::kSize, kNone); - Heap::RootListIndex heap_map_index = Heap::kMutableHeapNumberMapRootIndex; - StoreMapNoWriteBarrier(result, heap_map_index); - return UncheckedCast(result); -} - -TNode CodeStubAssembler::AllocateMutableHeapNumberWithValue( - SloppyTNode value) { - TNode result = AllocateMutableHeapNumber(); - StoreMutableHeapNumberValue(result, value); - return result; -} - TNode CodeStubAssembler::AllocateBigInt(TNode length) { TNode result = AllocateRawBigInt(length); StoreBigIntBitfield(result, WordShl(length, BigInt::LengthBits::kShift)); diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h index 2c6e9465a0..f4b19c562c 100644 --- a/src/code-stub-assembler.h +++ b/src/code-stub-assembler.h @@ -1075,8 +1075,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { // Store the floating point value of a HeapNumber. void StoreHeapNumberValue(SloppyTNode object, SloppyTNode value); - void StoreMutableHeapNumberValue(SloppyTNode object, - SloppyTNode value); // Store a field to an object on the heap. Node* StoreObjectField(Node* object, int 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); // Allocate a HeapNumber without initializing its value. - TNode AllocateHeapNumber(); + TNode AllocateHeapNumber(MutableMode mode = IMMUTABLE); // Allocate a HeapNumber with a specific value. - TNode AllocateHeapNumberWithValue(SloppyTNode value); - TNode AllocateHeapNumberWithValue(double value) { - return AllocateHeapNumberWithValue(Float64Constant(value)); - } - - // Allocate a MutableHeapNumber with a specific value. - TNode AllocateMutableHeapNumberWithValue( - SloppyTNode value); + TNode AllocateHeapNumberWithValue(SloppyTNode value, + MutableMode mode = IMMUTABLE); // Allocate a BigInt with {length} digits. Sets the sign bit to {false}. // Does not initialize the digits. @@ -1184,6 +1176,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { TNode LoadBigIntBitfield(TNode bigint); TNode LoadBigIntDigit(TNode bigint, int digit_index); + TNode AllocateHeapNumberWithValue(double value, + MutableMode mode = IMMUTABLE) { + return AllocateHeapNumberWithValue(Float64Constant(value), mode); + } + // Allocate a SeqOneByteString with the given length. TNode AllocateSeqOneByteString(int length, AllocationFlags flags = kNone); @@ -2743,9 +2740,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { TNode length, TNode first, TNode second, AllocationFlags flags); - // Allocate a MutableHeapNumber without initializing its value. - TNode AllocateMutableHeapNumber(); - Node* SelectImpl(TNode condition, const NodeGenerator& true_body, const NodeGenerator& false_body, MachineRepresentation rep); diff --git a/src/compiler/code-assembler.cc b/src/compiler/code-assembler.cc index f232c47734..623c46a11b 100644 --- a/src/compiler/code-assembler.cc +++ b/src/compiler/code-assembler.cc @@ -266,8 +266,8 @@ TNode CodeAssembler::NumberConstant(double value) { // deferring allocation to code generation // (see AllocateAndInstallRequestedHeapObjects) since that makes it easier // to generate constant lookups for embedded builtins. - return UncheckedCast( - HeapConstant(isolate()->factory()->NewHeapNumber(value, TENURED))); + return UncheckedCast(HeapConstant( + isolate()->factory()->NewHeapNumber(value, IMMUTABLE, TENURED))); } } diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index af10e0de45..4e0fcf62a4 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -3464,9 +3464,9 @@ void TranslatedState::MaterializeMutableHeapNumber(TranslatedFrame* frame, CHECK_NE(TranslatedValue::kCapturedObject, frame->values_[*value_index].kind()); Handle value = frame->values_[*value_index].GetValue(); + Handle box; CHECK(value->IsNumber()); - Handle box = - isolate()->factory()->NewMutableHeapNumber(value->Number()); + box = isolate()->factory()->NewHeapNumber(value->Number(), MUTABLE); (*value_index)++; slot->set_storage(box); } diff --git a/src/heap/factory-inl.h b/src/heap/factory-inl.h index 85f2679b3f..85aa808da4 100644 --- a/src/heap/factory-inl.h +++ b/src/heap/factory-inl.h @@ -117,37 +117,23 @@ Handle Factory::NewNumberFromInt64(int64_t value, return NewNumber(static_cast(value), pretenure); } -Handle Factory::NewHeapNumber(double value, +Handle Factory::NewHeapNumber(double value, MutableMode mode, PretenureFlag pretenure) { - Handle heap_number = NewHeapNumber(pretenure); + Handle heap_number = NewHeapNumber(mode, pretenure); heap_number->set_value(value); return heap_number; } -Handle Factory::NewMutableHeapNumber( - double value, PretenureFlag pretenure) { - Handle number = NewMutableHeapNumber(pretenure); - number->set_value(value); - return number; -} - Handle Factory::NewHeapNumberFromBits(uint64_t bits, + MutableMode mode, PretenureFlag pretenure) { - Handle heap_number = NewHeapNumber(pretenure); + Handle heap_number = NewHeapNumber(mode, pretenure); heap_number->set_value_as_bits(bits); return heap_number; } -Handle Factory::NewMutableHeapNumberFromBits( - uint64_t bits, PretenureFlag pretenure) { - Handle number = NewMutableHeapNumber(pretenure); - number->set_value_as_bits(bits); - return number; -} - -Handle Factory::NewMutableHeapNumberWithHoleNaN( - PretenureFlag pretenure) { - return NewMutableHeapNumberFromBits(kHoleNanInt64, pretenure); +Handle Factory::NewMutableHeapNumber(PretenureFlag pretenure) { + return NewHeapNumberFromBits(kHoleNanInt64, MUTABLE, pretenure); } Handle Factory::NewJSArrayWithElements(Handle elements, diff --git a/src/heap/factory.cc b/src/heap/factory.cc index a59c0c04d0..0d8846d1f4 100644 --- a/src/heap/factory.cc +++ b/src/heap/factory.cc @@ -2112,14 +2112,16 @@ Handle Factory::NewNumber(double value, PretenureFlag pretenure) { if (DoubleToSmiInteger(value, &int_value)) { return handle(Smi::FromInt(int_value), isolate()); } - return NewHeapNumber(value, pretenure); + + // Materialize the value in the heap. + return NewHeapNumber(value, IMMUTABLE, pretenure); } Handle Factory::NewNumberFromInt(int32_t value, PretenureFlag pretenure) { if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate()); // Bypass NewNumber to avoid various redundant checks. - return NewHeapNumber(FastI2D(value), pretenure); + return NewHeapNumber(FastI2D(value), IMMUTABLE, pretenure); } Handle Factory::NewNumberFromUint(uint32_t value, @@ -2128,26 +2130,18 @@ Handle Factory::NewNumberFromUint(uint32_t value, if (int32v >= 0 && Smi::IsValid(int32v)) { return handle(Smi::FromInt(int32v), isolate()); } - return NewHeapNumber(FastUI2D(value), pretenure); + return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure); } -Handle Factory::NewHeapNumber(PretenureFlag pretenure) { +Handle Factory::NewHeapNumber(MutableMode mode, + PretenureFlag pretenure) { 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, map, kDoubleUnaligned); return handle(HeapNumber::cast(result), isolate()); } -Handle 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 Factory::NewBigInt(int length, PretenureFlag pretenure) { if (length < 0 || length > BigInt::kMaxLength) { diff --git a/src/heap/factory.h b/src/heap/factory.h index 991c4429e2..2980138a0b 100644 --- a/src/heap/factory.h +++ b/src/heap/factory.h @@ -527,21 +527,18 @@ class V8_EXPORT_PRIVATE Factory { inline Handle NewNumberFromInt64( int64_t value, PretenureFlag pretenure = NOT_TENURED); inline Handle NewHeapNumber( - double value, PretenureFlag pretenure = NOT_TENURED); + double value, MutableMode mode = IMMUTABLE, + PretenureFlag pretenure = NOT_TENURED); inline Handle 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 NewMutableHeapNumber( + PretenureFlag pretenure = NOT_TENURED); // Creates heap number object with not yet set value field. - Handle NewHeapNumber(PretenureFlag pretenure = NOT_TENURED); - - Handle NewMutableHeapNumber( - PretenureFlag pretenure = NOT_TENURED); - inline Handle NewMutableHeapNumber( - double value, PretenureFlag pretenure = NOT_TENURED); - inline Handle NewMutableHeapNumberFromBits( - uint64_t bits, PretenureFlag pretenure = NOT_TENURED); - inline Handle NewMutableHeapNumberWithHoleNaN( - PretenureFlag pretenure = NOT_TENURED); + Handle NewHeapNumber(MutableMode mode, + PretenureFlag pretenure = NOT_TENURED); // Allocates a new BigInt with {length} digits. Only to be used by // MutableBigInt::New*. diff --git a/src/heap/setup-heap-internal.cc b/src/heap/setup-heap-internal.cc index e59ea0d955..26c04c8b10 100644 --- a/src/heap/setup-heap-internal.cc +++ b/src/heap/setup-heap-internal.cc @@ -368,7 +368,7 @@ bool Heap::CreateInitialMaps() { ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector) ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number, Context::NUMBER_FUNCTION_INDEX) - ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, MutableHeapNumber::kSize, + ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize, mutable_heap_number) ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol, Context::SYMBOL_FUNCTION_INDEX) @@ -586,16 +586,18 @@ void Heap::CreateInitialObjects() { Factory* factory = isolate()->factory(); // 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())); set_nan_value(*factory->NewHeapNumber( - std::numeric_limits::quiet_NaN(), TENURED_READ_ONLY)); - set_hole_nan_value( - *factory->NewHeapNumberFromBits(kHoleNanInt64, TENURED_READ_ONLY)); - set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, TENURED_READ_ONLY)); + std::numeric_limits::quiet_NaN(), IMMUTABLE, TENURED_READ_ONLY)); + set_hole_nan_value(*factory->NewHeapNumberFromBits(kHoleNanInt64, IMMUTABLE, + TENURED_READ_ONLY)); + set_infinity_value( + *factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED_READ_ONLY)); 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. set_single_character_string_cache( diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc index c6a22285a6..7452732399 100644 --- a/src/ia32/assembler-ia32.cc +++ b/src/ia32/assembler-ia32.cc @@ -303,8 +303,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); break; case HeapObjectRequest::kCodeStub: request.code_stub()->set_isolate(isolate); diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc index 43a1581894..ee24a5f290 100644 --- a/src/ic/accessor-assembler.cc +++ b/src/ic/accessor-assembler.cc @@ -1091,7 +1091,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( } else { if (do_transitioning_store) { Node* mutable_heap_number = - AllocateMutableHeapNumberWithValue(double_value); + AllocateHeapNumberWithValue(double_value, MUTABLE); StoreMap(object, object_map); StoreObjectField(object, field_offset, mutable_heap_number); } else { @@ -1130,7 +1130,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( { Node* double_value = ChangeNumberToFloat64(value); Node* mutable_heap_number = - AllocateMutableHeapNumberWithValue(double_value); + AllocateHeapNumberWithValue(double_value, MUTABLE); var_value.Bind(mutable_heap_number); Goto(&cont); } diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc index 25e24d39f3..031d47be8c 100644 --- a/src/mips/assembler-mips.cc +++ b/src/mips/assembler-mips.cc @@ -262,8 +262,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); break; case HeapObjectRequest::kCodeStub: request.code_stub()->set_isolate(isolate); diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc index 98f405d222..126a8c1528 100644 --- a/src/mips64/assembler-mips64.cc +++ b/src/mips64/assembler-mips64.cc @@ -241,8 +241,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); break; case HeapObjectRequest::kCodeStub: request.code_stub()->set_isolate(isolate); diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 2602a420f6..e80be8d6ff 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -110,8 +110,10 @@ void Smi::SmiVerify(Isolate* isolate) { void HeapObject::HeapObjectVerify(Isolate* isolate) { VerifyHeapPointer(map()); 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: STRING_TYPE_LIST(STRING_TYPE_CASE) #undef STRING_TYPE_CASE @@ -124,10 +126,8 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { Map::cast(this)->MapVerify(isolate); break; case HEAP_NUMBER_TYPE: - CHECK(IsHeapNumber()); - break; case MUTABLE_HEAP_NUMBER_TYPE: - CHECK(IsMutableHeapNumber()); + HeapNumber::cast(this)->HeapNumberVerify(isolate); break; case BIGINT_TYPE: BigInt::cast(this)->BigIntVerify(isolate); @@ -372,6 +372,10 @@ void Symbol::SymbolVerify(Isolate* isolate) { CHECK_IMPLIES(IsPrivateField(), IsPrivate()); } +void HeapNumber::HeapNumberVerify(Isolate* isolate) { + CHECK(IsHeapNumber() || IsMutableHeapNumber()); +} + void ByteArray::ByteArrayVerify(Isolate* isolate) { CHECK(IsByteArray()); } void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) { diff --git a/src/objects-inl.h b/src/objects-inl.h index db30108c46..f7ee1013c3 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -640,9 +640,7 @@ CAST_ACCESSOR(JSProxy) CAST_ACCESSOR(JSReceiver) CAST_ACCESSOR(JSStringIterator) CAST_ACCESSOR(JSValue) -CAST_ACCESSOR(HeapNumber) CAST_ACCESSOR(LayoutDescriptor) -CAST_ACCESSOR(MutableHeapNumber) CAST_ACCESSOR(NameDictionary) CAST_ACCESSOR(NormalizedMapCache) CAST_ACCESSOR(NumberDictionary) @@ -707,13 +705,12 @@ bool Object::FilterKey(PropertyFilter filter) { Handle Object::NewStorageFor(Isolate* isolate, Handle object, Representation representation) { if (!representation.IsDouble()) return object; - auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + Handle result = isolate->factory()->NewHeapNumber(MUTABLE); if (object->IsUninitialized(isolate)) { result->set_value_as_bits(kHoleNanInt64); } else if (object->IsMutableHeapNumber()) { // Ensure that all bits of the double value are preserved. - result->set_value_as_bits( - MutableHeapNumber::cast(*object)->value_as_bits()); + result->set_value_as_bits(HeapNumber::cast(*object)->value_as_bits()); } else { result->set_value(object->Number()); } @@ -727,8 +724,7 @@ Handle Object::WrapForRead(Isolate* isolate, Handle object, DCHECK(object->FitsRepresentation(representation)); return object; } - return isolate->factory()->NewHeapNumber( - MutableHeapNumber::cast(*object)->value()); + return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value()); } Representation Object::OptimalRepresentation() { @@ -1122,28 +1118,30 @@ void HeapObject::synchronized_set_map_word(MapWord map_word) { int HeapObject::Size() const { return SizeFromMap(map()); } -double HeapNumberBase::value() const { +double HeapNumber::value() const { return READ_DOUBLE_FIELD(this, kValueOffset); } -void HeapNumberBase::set_value(double value) { + +void HeapNumber::set_value(double 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); } -void HeapNumberBase::set_value_as_bits(uint64_t bits) { +void HeapNumber::set_value_as_bits(uint64_t bits) { WRITE_UINT64_FIELD(this, kValueOffset, bits); } -int HeapNumberBase::get_exponent() { +int HeapNumber::get_exponent() { return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >> kExponentShift) - kExponentBias; } -int HeapNumberBase::get_sign() { + +int HeapNumber::get_sign() { return READ_INT_FIELD(this, kExponentOffset) & kSignMask; } @@ -1626,8 +1624,8 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { if (IsUnboxedDoubleField(index)) { DCHECK(value->IsMutableHeapNumber()); // Ensure that all bits of the double value are preserved. - RawFastDoublePropertyAsBitsAtPut( - index, MutableHeapNumber::cast(value)->value_as_bits()); + RawFastDoublePropertyAsBitsAtPut(index, + HeapNumber::cast(value)->value_as_bits()); } else { RawFastPropertyAtPut(index, value); } @@ -1658,7 +1656,8 @@ void JSObject::WriteToField(int descriptor, PropertyDetails details, if (IsUnboxedDoubleField(index)) { RawFastDoublePropertyAsBitsAtPut(index, bits); } else { - auto box = MutableHeapNumber::cast(RawFastPropertyAt(index)); + HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); + DCHECK(box->IsMutableHeapNumber()); box->set_value_as_bits(bits); } } else { @@ -2731,6 +2730,18 @@ SMI_ACCESSORS(JSAsyncGeneratorObject, is_awaiting, kIsAwaitingOffset) ACCESSORS(JSValue, value, Object, kValueOffset) +HeapNumber* HeapNumber::cast(Object* object) { + SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber()); + return reinterpret_cast(object); +} + + +const HeapNumber* HeapNumber::cast(const Object* object) { + SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber()); + return reinterpret_cast(object); +} + + ACCESSORS(JSDate, value, Object, kValueOffset) ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset) ACCESSORS(JSDate, year, Object, kYearOffset) diff --git a/src/objects-printer.cc b/src/objects-printer.cc index 38c406a7bd..d4b273e5ac 100644 --- a/src/objects-printer.cc +++ b/src/objects-printer.cc @@ -89,7 +89,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT break; case MUTABLE_HEAP_NUMBER_TYPE: os << "MutableHeapNumberPrint(os); + HeapNumber::cast(this)->HeapNumberPrint(os); os << ">\n"; break; case BIGINT_TYPE: @@ -2144,12 +2144,6 @@ void MaybeObject::Print(std::ostream& os) { #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. void Name::NameShortPrint() { if (this->IsString()) { diff --git a/src/objects.cc b/src/objects.cc index 43a45ab1eb..909394f669 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3449,14 +3449,14 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT break; } case HEAP_NUMBER_TYPE: { - os << "HeapNumberPrint(os); os << ">"; break; } case MUTABLE_HEAP_NUMBER_TYPE: { - os << "MutableHeapNumberPrint(os); + os << "HeapNumberPrint(os); os << '>'; break; } @@ -3562,6 +3562,10 @@ bool HeapObject::IsValidSlot(Map* map, int offset) { this, offset, 0); } +void HeapNumber::HeapNumberPrint(std::ostream& os) { // NOLINT + os << value(); +} + String* JSReceiver::class_name() { if (IsFunction()) return GetHeap()->Function_string(); if (IsJSArgumentsObject()) return GetHeap()->Arguments_string(); @@ -3999,7 +4003,7 @@ void MigrateFastToFast(Handle object, Handle new_map) { FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); DCHECK(details.representation().IsDouble()); DCHECK(!new_map->IsUnboxedDoubleField(index)); - auto value = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + Handle value = isolate->factory()->NewMutableHeapNumber(); object->RawFastPropertyAtPut(index, *value); object->synchronized_set_map(*new_map); return; @@ -4015,7 +4019,7 @@ void MigrateFastToFast(Handle object, Handle new_map) { // Properly initialize newly added property. Handle value; if (details.representation().IsDouble()) { - value = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + value = isolate->factory()->NewMutableHeapNumber(); } else { value = isolate->factory()->uninitialized_value(); } @@ -4079,7 +4083,7 @@ void MigrateFastToFast(Handle object, Handle new_map) { // must already be prepared for data of certain type. DCHECK(!details.representation().IsNone()); if (details.representation().IsDouble()) { - value = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + value = isolate->factory()->NewMutableHeapNumber(); } else { value = isolate->factory()->uninitialized_value(); } @@ -4093,11 +4097,9 @@ void MigrateFastToFast(Handle object, Handle new_map) { FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); if (object->IsUnboxedDoubleField(index)) { uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index); - if (representation.IsDouble()) { - value = isolate->factory()->NewMutableHeapNumberFromBits(old_bits); - } else { - value = isolate->factory()->NewHeapNumberFromBits(old_bits); - } + value = isolate->factory()->NewHeapNumberFromBits( + old_bits, representation.IsDouble() ? MUTABLE : IMMUTABLE); + } else { value = handle(object->RawFastPropertyAt(index), isolate); if (!old_representation.IsDouble() && representation.IsDouble()) { @@ -4125,7 +4127,7 @@ void MigrateFastToFast(Handle object, Handle new_map) { DCHECK_EQ(kData, details.kind()); Handle value; if (details.representation().IsDouble()) { - value = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + value = isolate->factory()->NewMutableHeapNumber(); } else { value = isolate->factory()->uninitialized_value(); } @@ -4158,7 +4160,7 @@ void MigrateFastToFast(Handle object, Handle new_map) { DCHECK(value->IsMutableHeapNumber()); // Ensure that all bits of the double value are preserved. 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)) { // Transition from tagged to untagged slot. heap->ClearRecordedSlot(*object, @@ -4231,8 +4233,8 @@ void MigrateFastToSlow(Handle object, Handle new_map, value = handle(object->RawFastPropertyAt(index), isolate); if (details.representation().IsDouble()) { DCHECK(value->IsMutableHeapNumber()); - double old_value = Handle::cast(value)->value(); - value = isolate->factory()->NewHeapNumber(old_value); + Handle old = Handle::cast(value); + value = isolate->factory()->NewHeapNumber(old->value()); } } } else { @@ -5974,7 +5976,7 @@ void JSObject::AllocateStorageForMap(Handle object, Handle map) { if (!representation.IsDouble()) continue; FieldIndex index = FieldIndex::ForDescriptor(*map, i); if (map->IsUnboxedDoubleField(index)) continue; - auto box = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + Handle box = isolate->factory()->NewMutableHeapNumber(); if (index.is_inobject()) { storage->set(index.property_index(), *box); } else { diff --git a/src/objects.h b/src/objects.h index d833029709..d5f39ecd76 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1981,11 +1981,10 @@ class FixedBodyDescriptor; template class FlexibleBodyDescriptor; + // The HeapNumber class describes heap allocated numbers that cannot be -// represented in a Smi (small integer). MutableHeapNumber is the same, but its -// number value can change over time (it is used only as property storage). -// HeapNumberBase merely exists to avoid code duplication. -class HeapNumberBase : public HeapObject { +// represented in a Smi (small integer) +class HeapNumber: public HeapObject { public: // [value]: number value. inline double value() const; @@ -1994,6 +1993,11 @@ class HeapNumberBase : public HeapObject { inline uint64_t value_as_bits() const; 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_sign(); @@ -2027,25 +2031,7 @@ class HeapNumberBase : public HeapObject { static const int kNonMantissaBitsInTopWord = 12; private: - DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumberBase) -}; - -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) + DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber); }; enum EnsureElementsMode { diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc index 0dc6904e78..5ab1278d8c 100644 --- a/src/ppc/assembler-ppc.cc +++ b/src/ppc/assembler-ppc.cc @@ -222,8 +222,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); break; case HeapObjectRequest::kCodeStub: request.code_stub()->set_isolate(isolate); diff --git a/src/runtime/runtime-literals.cc b/src/runtime/runtime-literals.cc index 0d989eef99..2269c304e0 100644 --- a/src/runtime/runtime-literals.cc +++ b/src/runtime/runtime-literals.cc @@ -122,9 +122,9 @@ MaybeHandle JSObjectWalkVisitor::StructureWalk( if (copying) copy->FastPropertyAtPut(index, *value); } else if (copying && raw->IsMutableHeapNumber()) { DCHECK(descriptors->GetDetails(i).representation().IsDouble()); - uint64_t double_value = MutableHeapNumber::cast(raw)->value_as_bits(); - auto value = - isolate->factory()->NewMutableHeapNumberFromBits(double_value); + uint64_t double_value = HeapNumber::cast(raw)->value_as_bits(); + Handle value = isolate->factory()->NewHeapNumber(MUTABLE); + value->set_value_as_bits(double_value); copy->FastPropertyAtPut(index, *value); } } diff --git a/src/s390/assembler-s390.cc b/src/s390/assembler-s390.cc index 0fccb0ebe8..4a5138d07a 100644 --- a/src/s390/assembler-s390.cc +++ b/src/s390/assembler-s390.cc @@ -327,8 +327,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast
(buffer_ + request.offset()); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + object = isolate->factory()->NewHeapNumber(request.heap_number(), + IMMUTABLE, TENURED); set_target_address_at(pc, kNullAddress, reinterpret_cast
(object.location()), SKIP_ICACHE_FLUSH); diff --git a/src/value-serializer.cc b/src/value-serializer.cc index 6cf86a6a20..34f276e46f 100644 --- a/src/value-serializer.cc +++ b/src/value-serializer.cc @@ -356,10 +356,8 @@ Maybe ValueSerializer::WriteObject(Handle object) { WriteOddball(Oddball::cast(*object)); return ThrowIfOutOfMemory(); case HEAP_NUMBER_TYPE: - WriteHeapNumber(HeapNumber::cast(*object)); - return ThrowIfOutOfMemory(); case MUTABLE_HEAP_NUMBER_TYPE: - WriteMutableHeapNumber(MutableHeapNumber::cast(*object)); + WriteHeapNumber(HeapNumber::cast(*object)); return ThrowIfOutOfMemory(); case BIGINT_TYPE: WriteBigInt(BigInt::cast(*object)); @@ -427,11 +425,6 @@ void ValueSerializer::WriteHeapNumber(HeapNumber* number) { WriteDouble(number->value()); } -void ValueSerializer::WriteMutableHeapNumber(MutableHeapNumber* number) { - WriteTag(SerializationTag::kDouble); - WriteDouble(number->value()); -} - void ValueSerializer::WriteBigInt(BigInt* bigint) { WriteTag(SerializationTag::kBigInt); WriteBigIntContents(bigint); diff --git a/src/value-serializer.h b/src/value-serializer.h index 91f8ecc7dd..e162ce22d7 100644 --- a/src/value-serializer.h +++ b/src/value-serializer.h @@ -29,7 +29,6 @@ class JSMap; class JSRegExp; class JSSet; class JSValue; -class MutableHeapNumber; class Object; class Oddball; class Smi; @@ -116,7 +115,6 @@ class ValueSerializer { void WriteOddball(Oddball* oddball); void WriteSmi(Smi* smi); void WriteHeapNumber(HeapNumber* number); - void WriteMutableHeapNumber(MutableHeapNumber* number); void WriteBigInt(BigInt* bigint); void WriteString(Handle string); Maybe WriteJSReceiver(Handle receiver) diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index 14c383d09b..1c3835fbbe 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -339,8 +339,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast
(buffer_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - Handle object = - isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); + Handle object = isolate->factory()->NewHeapNumber( + request.heap_number(), IMMUTABLE, TENURED); Memory::Object_Handle_at(pc) = object; break; } diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc index 9ac367db69..87c7de08a2 100644 --- a/test/cctest/test-assembler-mips.cc +++ b/test/cctest/test-assembler-mips.cc @@ -3293,7 +3293,7 @@ TEST(jump_tables3) { Handle values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { 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]; Object* obj; diff --git a/test/cctest/test-assembler-mips64.cc b/test/cctest/test-assembler-mips64.cc index a80000f936..24c9d2230c 100644 --- a/test/cctest/test-assembler-mips64.cc +++ b/test/cctest/test-assembler-mips64.cc @@ -3423,7 +3423,7 @@ TEST(jump_tables3) { Handle values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { 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]; Object* obj; diff --git a/test/cctest/test-field-type-tracking.cc b/test/cctest/test-field-type-tracking.cc index 9005603839..cd42122b21 100644 --- a/test/cctest/test-field-type-tracking.cc +++ b/test/cctest/test-field-type-tracking.cc @@ -2777,10 +2777,10 @@ TEST(HoleyMutableHeapNumber) { v8::HandleScope scope(CcTest::isolate()); Isolate* isolate = CcTest::i_isolate(); - auto mhn = isolate->factory()->NewMutableHeapNumberWithHoleNaN(); + Handle mhn = isolate->factory()->NewMutableHeapNumber(); 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()); mhn->set_value_as_bits(kHoleNanInt64); @@ -2793,11 +2793,11 @@ TEST(HoleyMutableHeapNumber) { Object::NewStorageFor(isolate, isolate->factory()->uninitialized_value(), Representation::Double()); 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()); 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 diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc index d38ab3ea09..6314baef61 100644 --- a/test/cctest/test-unboxed-doubles.cc +++ b/test/cctest/test-unboxed-doubles.cc @@ -1100,7 +1100,7 @@ TEST(DoScavenge) { double boom_value = bit_cast(fake_object); FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0); - auto boom_number = factory->NewMutableHeapNumber(boom_value); + Handle boom_number = factory->NewHeapNumber(boom_value, MUTABLE); obj->FastPropertyAtPut(field_index, *boom_number); // Now |obj| moves to old gen and it has a double field that looks like