• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_HEAP_FACTORY_BASE_INL_H_
6 #define V8_HEAP_FACTORY_BASE_INL_H_
7 
8 #include "src/heap/factory-base.h"
9 #include "src/numbers/conversions.h"
10 #include "src/objects/heap-number.h"
11 #include "src/objects/map.h"
12 #include "src/objects/slots-inl.h"
13 #include "src/objects/smi.h"
14 #include "src/roots/roots.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 template <typename Impl>
ToBoolean(bool value)20 Handle<Oddball> FactoryBase<Impl>::ToBoolean(bool value) {
21   return value ? impl()->true_value() : impl()->false_value();
22 }
23 
24 template <typename Impl>
25 template <AllocationType allocation>
NewNumber(double value)26 Handle<Object> FactoryBase<Impl>::NewNumber(double value) {
27   // Materialize as a SMI if possible.
28   int32_t int_value;
29   if (DoubleToSmiInteger(value, &int_value)) {
30     return handle(Smi::FromInt(int_value), isolate());
31   }
32   return NewHeapNumber<allocation>(value);
33 }
34 
35 template <typename Impl>
36 template <AllocationType allocation>
NewNumberFromInt(int32_t value)37 Handle<Object> FactoryBase<Impl>::NewNumberFromInt(int32_t value) {
38   if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
39   // Bypass NewNumber to avoid various redundant checks.
40   return NewHeapNumber<allocation>(FastI2D(value));
41 }
42 
43 template <typename Impl>
44 template <AllocationType allocation>
NewNumberFromUint(uint32_t value)45 Handle<Object> FactoryBase<Impl>::NewNumberFromUint(uint32_t value) {
46   int32_t int32v = static_cast<int32_t>(value);
47   if (int32v >= 0 && Smi::IsValid(int32v)) {
48     return handle(Smi::FromInt(int32v), isolate());
49   }
50   return NewHeapNumber<allocation>(FastUI2D(value));
51 }
52 
53 template <typename Impl>
54 template <AllocationType allocation>
NewNumberFromSize(size_t value)55 Handle<Object> FactoryBase<Impl>::NewNumberFromSize(size_t value) {
56   // We can't use Smi::IsValid() here because that operates on a signed
57   // intptr_t, and casting from size_t could create a bogus sign bit.
58   if (value <= static_cast<size_t>(Smi::kMaxValue)) {
59     return handle(Smi::FromIntptr(static_cast<intptr_t>(value)), isolate());
60   }
61   return NewHeapNumber<allocation>(static_cast<double>(value));
62 }
63 
64 template <typename Impl>
65 template <AllocationType allocation>
NewNumberFromInt64(int64_t value)66 Handle<Object> FactoryBase<Impl>::NewNumberFromInt64(int64_t value) {
67   if (value <= std::numeric_limits<int32_t>::max() &&
68       value >= std::numeric_limits<int32_t>::min() &&
69       Smi::IsValid(static_cast<int32_t>(value))) {
70     return handle(Smi::FromInt(static_cast<int32_t>(value)), isolate());
71   }
72   return NewHeapNumber<allocation>(static_cast<double>(value));
73 }
74 
75 template <typename Impl>
76 template <AllocationType allocation>
NewHeapNumber(double value)77 Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumber(double value) {
78   Handle<HeapNumber> heap_number = NewHeapNumber<allocation>();
79   heap_number->set_value(value, kRelaxedStore);
80   return heap_number;
81 }
82 
83 template <typename Impl>
84 template <AllocationType allocation>
NewHeapNumberFromBits(uint64_t bits)85 Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumberFromBits(uint64_t bits) {
86   Handle<HeapNumber> heap_number = NewHeapNumber<allocation>();
87   heap_number->set_value_as_bits(bits, kRelaxedStore);
88   return heap_number;
89 }
90 
91 template <typename Impl>
92 template <AllocationType allocation>
NewHeapNumberWithHoleNaN()93 Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumberWithHoleNaN() {
94   return NewHeapNumberFromBits<allocation>(kHoleNanInt64);
95 }
96 
97 template <typename Impl>
98 template <typename StructType>
NewStructInternal(InstanceType type,AllocationType allocation)99 StructType FactoryBase<Impl>::NewStructInternal(InstanceType type,
100                                                 AllocationType allocation) {
101   ReadOnlyRoots roots = read_only_roots();
102   Map map = Map::GetInstanceTypeMap(roots, type);
103   int size = StructType::kSize;
104   return StructType::cast(NewStructInternal(roots, map, size, allocation));
105 }
106 
107 template <typename Impl>
NewStructInternal(ReadOnlyRoots roots,Map map,int size,AllocationType allocation)108 Struct FactoryBase<Impl>::NewStructInternal(ReadOnlyRoots roots, Map map,
109                                             int size,
110                                             AllocationType allocation) {
111   DCHECK_EQ(size, map.instance_size());
112   HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
113   Struct str = Struct::cast(result);
114   Object value = roots.undefined_value();
115   int length = (size >> kTaggedSizeLog2) - 1;
116   MemsetTagged(str.RawField(Struct::kHeaderSize), value, length);
117   return str;
118 }
119 
120 }  // namespace internal
121 }  // namespace v8
122 
123 #endif  // V8_HEAP_FACTORY_BASE_INL_H_
124