summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/heap/factory-base.h
blob: 23d6ebb01318ec4de7441b94a1070312d540614f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_HEAP_FACTORY_BASE_H_
#define V8_HEAP_FACTORY_BASE_H_

#include "src/base/export-template.h"
#include "src/base/strings.h"
#include "src/common/globals.h"
#include "src/handles/maybe-handles.h"
#include "src/objects/code-kind.h"
#include "src/objects/function-kind.h"
#include "src/objects/instance-type.h"
#include "src/roots/roots.h"
#include "torque-generated/class-forward-declarations.h"

namespace v8 {
namespace internal {

class ArrayBoilerplateDescription;
class BytecodeArray;
class ClassPositions;
class CoverageInfo;
class DeoptimizationLiteralArray;
class DeoptimizationFrameTranslation;
class FixedArray;
template <typename T>
class FixedIntegerArray;
class FreshlyAllocatedBigInt;
class FunctionLiteral;
class HeapObject;
class ObjectBoilerplateDescription;
template <typename T>
class PodArray;
class PreparseData;
class RegExpBoilerplateDescription;
class SeqOneByteString;
class SeqTwoByteString;
class SharedFunctionInfo;
class SourceTextModuleInfo;
class TemplateObjectDescription;
class UncompiledDataWithoutPreparseData;
class UncompiledDataWithPreparseData;
struct SourceRange;
enum class Builtin : int32_t;
template <typename T>
class ZoneVector;

namespace wasm {
class ValueType;
}  // namespace wasm

template <typename Impl>
class FactoryBase;

enum class NumberCacheMode { kIgnore, kSetOnly, kBoth };

using FixedInt32Array = FixedIntegerArray<int32_t>;
using FixedUInt32Array = FixedIntegerArray<uint32_t>;

// Putting Torque-generated definitions in a superclass allows to shadow them
// easily when they shouldn't be used and to reference them when they happen to
// have the same signature.
template <typename Impl>
class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) TorqueGeneratedFactory {
 private:
  FactoryBase<Impl>* factory() { return static_cast<FactoryBase<Impl>*>(this); }

 public:
#include "torque-generated/factory.inc"
};

struct NewCodeOptions {
  CodeKind kind;
  Builtin builtin;
  bool is_turbofanned;
  int stack_slots;
  int instruction_size;
  int metadata_size;
  unsigned int inlined_bytecode_size;
  BytecodeOffset osr_offset;
  int handler_table_offset;
  int constant_pool_offset;
  int code_comments_offset;
  int32_t unwinding_info_offset;
  Handle<HeapObject> bytecode_or_deoptimization_data;
  Handle<ByteArray> bytecode_offsets_or_source_position_table;
  // Either instruction_stream is set and instruction_start is kNullAddress, or
  // instruction_stream is empty and instruction_start a valid target.
  MaybeHandle<InstructionStream> instruction_stream;
  Address instruction_start;
};

template <typename Impl>
class FactoryBase : public TorqueGeneratedFactory<Impl> {
 public:
  Handle<Code> NewCode(const NewCodeOptions& options);

  // Converts the given boolean condition to JavaScript boolean value.
  inline Handle<Boolean> ToBoolean(bool value);

#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
  READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR

  // Numbers (e.g. literals) are pretenured by the parser.
  // The return value may be a smi or a heap number.
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<Object> NewNumber(double value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<Object> NewNumberFromInt(int32_t value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<Object> NewNumberFromUint(uint32_t value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<Object> NewNumberFromSize(size_t value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<Object> NewNumberFromInt64(int64_t value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<HeapNumber> NewHeapNumber(double value);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<HeapNumber> NewHeapNumberFromBits(uint64_t bits);
  template <AllocationType allocation = AllocationType::kYoung>
  inline Handle<HeapNumber> NewHeapNumberWithHoleNaN();

  template <AllocationType allocation>
  Handle<HeapNumber> NewHeapNumber();

  Handle<Struct> NewStruct(InstanceType type,
                           AllocationType allocation = AllocationType::kYoung);

  // Create a pre-tenured empty AccessorPair.
  Handle<AccessorPair> NewAccessorPair();

  // Allocates a fixed array initialized with undefined values.
  Handle<FixedArray> NewFixedArray(
      int length, AllocationType allocation = AllocationType::kYoung);

  // Allocates a fixed array-like object with given map and initialized with
  // undefined values.
  Handle<FixedArray> NewFixedArrayWithMap(
      Handle<Map> map, int length,
      AllocationType allocation = AllocationType::kYoung);

  // Allocate a new fixed array with non-existing entries (the hole).
  Handle<FixedArray> NewFixedArrayWithHoles(
      int length, AllocationType allocation = AllocationType::kYoung);

  // Allocate a new fixed array with Smi(0) entries.
  Handle<FixedArray> NewFixedArrayWithZeroes(
      int length, AllocationType allocation = AllocationType::kYoung);

  // Allocate a new uninitialized fixed double array.
  // The function returns a pre-allocated empty fixed array for length = 0,
  // so the return type must be the general fixed array class.
  Handle<FixedArrayBase> NewFixedDoubleArray(
      int length, AllocationType allocation = AllocationType::kYoung);

  // Allocates a weak fixed array-like object with given map and initialized
  // with undefined values. Length must be > 0.
  Handle<WeakFixedArray> NewWeakFixedArrayWithMap(
      Tagged<Map> map, int length,
      AllocationType allocation = AllocationType::kYoung);

  // Allocates a fixed array which may contain in-place weak references. The
  // array is initialized with undefined values
  // The function returns a pre-allocated empty weak fixed array for length = 0.
  Handle<WeakFixedArray> NewWeakFixedArray(
      int length, AllocationType allocation = AllocationType::kYoung);

  // The function returns a pre-allocated empty byte array for length = 0.
  Handle<ByteArray> NewByteArray(
      int length, AllocationType allocation = AllocationType::kYoung);

  Handle<ExternalPointerArray> NewExternalPointerArray(
      int length, AllocationType allocation = AllocationType::kYoung);

  Handle<DeoptimizationLiteralArray> NewDeoptimizationLiteralArray(int length);
  Handle<DeoptimizationFrameTranslation> NewDeoptimizationFrameTranslation(
      int length);

  Handle<BytecodeArray> NewBytecodeArray(int length,
                                         const uint8_t* raw_bytecodes,
                                         int frame_size, int parameter_count,
                                         Handle<FixedArray> constant_pool);

  // Allocates a fixed array for name-value pairs of boilerplate properties and
  // calculates the number of properties we need to store in the backing store.
  Handle<ObjectBoilerplateDescription> NewObjectBoilerplateDescription(
      int boilerplate, int all_properties, int index_keys, bool has_seen_proto);

  // Create a new ArrayBoilerplateDescription struct.
  Handle<ArrayBoilerplateDescription> NewArrayBoilerplateDescription(
      ElementsKind elements_kind, Handle<FixedArrayBase> constant_values);

  Handle<RegExpBoilerplateDescription> NewRegExpBoilerplateDescription(
      Handle<FixedArray> data, Handle<String> source, Tagged<Smi> flags);

  // Create a new TemplateObjectDescription struct.
  Handle<TemplateObjectDescription> NewTemplateObjectDescription(
      Handle<FixedArray> raw_strings, Handle<FixedArray> cooked_strings);

  Handle<Script> NewScript(
      Handle<PrimitiveHeapObject> source,
      ScriptEventType event_type = ScriptEventType::kCreate);
  Handle<Script> NewScriptWithId(
      Handle<PrimitiveHeapObject> source, int script_id,
      ScriptEventType event_type = ScriptEventType::kCreate);

  Handle<ArrayList> NewArrayList(
      int size, AllocationType allocation = AllocationType::kYoung);

  Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral(
      FunctionLiteral* literal, Handle<Script> script, bool is_toplevel);

  // Create a copy of a given SharedFunctionInfo for use as a placeholder in
  // off-thread compilation
  Handle<SharedFunctionInfo> CloneSharedFunctionInfo(
      Handle<SharedFunctionInfo> other);

  Handle<PreparseData> NewPreparseData(int data_length, int children_length);

  Handle<UncompiledDataWithoutPreparseData>
  NewUncompiledDataWithoutPreparseData(Handle<String> inferred_name,
                                       int32_t start_position,
                                       int32_t end_position);

  Handle<UncompiledDataWithPreparseData> NewUncompiledDataWithPreparseData(
      Handle<String> inferred_name, int32_t start_position,
      int32_t end_position, Handle<PreparseData>);

  Handle<UncompiledDataWithoutPreparseDataWithJob>
  NewUncompiledDataWithoutPreparseDataWithJob(Handle<String> inferred_name,
                                              int32_t start_position,
                                              int32_t end_position);

  Handle<UncompiledDataWithPreparseDataAndJob>
  NewUncompiledDataWithPreparseDataAndJob(Handle<String> inferred_name,
                                          int32_t start_position,
                                          int32_t end_position,
                                          Handle<PreparseData>);

  // Allocates a FeedbackMetadata object and zeroes the data section.
  Handle<FeedbackMetadata> NewFeedbackMetadata(
      int slot_count, int create_closure_slot_count,
      AllocationType allocation = AllocationType::kOld);

  Handle<CoverageInfo> NewCoverageInfo(const ZoneVector<SourceRange>& slots);

  Handle<String> InternalizeString(base::Vector<const uint8_t> string,
                                   bool convert_encoding = false);
  Handle<String> InternalizeString(base::Vector<const uint16_t> string,
                                   bool convert_encoding = false);

  template <class StringTableKey>
  Handle<String> InternalizeStringWithKey(StringTableKey* key);

  Handle<SeqOneByteString> NewOneByteInternalizedString(
      base::Vector<const uint8_t> str, uint32_t raw_hash_field);
  Handle<SeqTwoByteString> NewTwoByteInternalizedString(
      base::Vector<const base::uc16> str, uint32_t raw_hash_field);
  Handle<SeqOneByteString> NewOneByteInternalizedStringFromTwoByte(
      base::Vector<const base::uc16> str, uint32_t raw_hash_field);

  Handle<SeqOneByteString> AllocateRawOneByteInternalizedString(
      int length, uint32_t raw_hash_field);
  Handle<SeqTwoByteString> AllocateRawTwoByteInternalizedString(
      int length, uint32_t raw_hash_field);

  // Creates a single character string where the character has given code.
  // A cache is used for Latin1 codes.
  Handle<String> LookupSingleCharacterStringFromCode(uint16_t code);

  MaybeHandle<String> NewStringFromOneByte(
      base::Vector<const uint8_t> string,
      AllocationType allocation = AllocationType::kYoung);

  inline Handle<String> NewStringFromAsciiChecked(
      const char* str, AllocationType allocation = AllocationType::kYoung) {
    return NewStringFromOneByte(base::OneByteVector(str), allocation)
        .ToHandleChecked();
  }

  // Allocates and partially initializes an one-byte or two-byte String. The
  // characters of the string are uninitialized. Currently used in regexp code
  // only, where they are pretenured.
  V8_WARN_UNUSED_RESULT MaybeHandle<SeqOneByteString> NewRawOneByteString(
      int length, AllocationType allocation = AllocationType::kYoung);
  V8_WARN_UNUSED_RESULT MaybeHandle<SeqTwoByteString> NewRawTwoByteString(
      int length, AllocationType allocation = AllocationType::kYoung);
  // Create a new cons string object which consists of a pair of strings.
  V8_WARN_UNUSED_RESULT MaybeHandle<String> NewConsString(
      Handle<String> left, Handle<String> right,
      AllocationType allocation = AllocationType::kYoung);

  V8_WARN_UNUSED_RESULT Handle<String> NewConsString(
      Handle<String> left, Handle<String> right, int length, bool one_byte,
      AllocationType allocation = AllocationType::kYoung);

  V8_WARN_UNUSED_RESULT Handle<String> NumberToString(
      Handle<Object> number, NumberCacheMode mode = NumberCacheMode::kBoth);
  V8_WARN_UNUSED_RESULT Handle<String> HeapNumberToString(
      Handle<HeapNumber> number, double value,
      NumberCacheMode mode = NumberCacheMode::kBoth);
  V8_WARN_UNUSED_RESULT Handle<String> SmiToString(
      Tagged<Smi> number, NumberCacheMode mode = NumberCacheMode::kBoth);

  V8_WARN_UNUSED_RESULT MaybeHandle<SeqOneByteString> NewRawSharedOneByteString(
      int length);
  V8_WARN_UNUSED_RESULT MaybeHandle<SeqTwoByteString> NewRawSharedTwoByteString(
      int length);

  // Allocates a new BigInt with {length} digits. Only to be used by
  // MutableBigInt::New*.
  Handle<FreshlyAllocatedBigInt> NewBigInt(
      int length, AllocationType allocation = AllocationType::kYoung);

  // Create a serialized scope info.
  Handle<ScopeInfo> NewScopeInfo(int length,
                                 AllocationType type = AllocationType::kOld);

  Handle<SourceTextModuleInfo> NewSourceTextModuleInfo();

  Handle<DescriptorArray> NewDescriptorArray(
      int number_of_descriptors, int slack = 0,
      AllocationType allocation = AllocationType::kYoung);

  Handle<ClassPositions> NewClassPositions(int start, int end);

  Handle<SwissNameDictionary> NewSwissNameDictionary(
      int at_least_space_for = kSwissNameDictionaryInitialCapacity,
      AllocationType allocation = AllocationType::kYoung);

  Handle<SwissNameDictionary> NewSwissNameDictionaryWithCapacity(
      int capacity, AllocationType allocation);

  Handle<FunctionTemplateRareData> NewFunctionTemplateRareData();

  MaybeHandle<Map> GetInPlaceInternalizedStringMap(Tagged<Map> from_string_map);

  AllocationType RefineAllocationTypeForInPlaceInternalizableString(
      AllocationType allocation, Tagged<Map> string_map);

 protected:
  // Must be large enough to fit any double, int, or size_t.
  static constexpr int kNumberToStringBufferSize = 32;

  // Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
  Tagged<HeapObject> AllocateRawArray(int size, AllocationType allocation);
  Tagged<HeapObject> AllocateRawFixedArray(int length,
                                           AllocationType allocation);
  Tagged<HeapObject> AllocateRawWeakArrayList(int length,
                                              AllocationType allocation);

  template <typename StructType>
  inline Tagged<StructType> NewStructInternal(InstanceType type,
                                              AllocationType allocation);
  Tagged<Struct> NewStructInternal(ReadOnlyRoots roots, Tagged<Map> map,
                                   int size, AllocationType allocation);

  Tagged<HeapObject> AllocateRawWithImmortalMap(
      int size, AllocationType allocation, Tagged<Map> map,
      AllocationAlignment alignment = kTaggedAligned);
  Tagged<HeapObject> NewWithImmortalMap(Tagged<Map> map,
                                        AllocationType allocation);

  Handle<FixedArray> NewFixedArrayWithFiller(Handle<Map> map, int length,
                                             Handle<HeapObject> filler,
                                             AllocationType allocation);

  Handle<SharedFunctionInfo> NewSharedFunctionInfo(AllocationType allocation);
  Handle<SharedFunctionInfo> NewSharedFunctionInfo(
      MaybeHandle<String> maybe_name,
      MaybeHandle<HeapObject> maybe_function_data, Builtin builtin,
      FunctionKind kind = FunctionKind::kNormalFunction);

  Handle<String> MakeOrFindTwoCharacterString(uint16_t c1, uint16_t c2);

  template <typename SeqStringT>
  MaybeHandle<SeqStringT> NewRawStringWithMap(int length, Tagged<Map> map,
                                              AllocationType allocation);

 private:
  Impl* impl() { return static_cast<Impl*>(this); }
  auto isolate() { return impl()->isolate(); }
  ReadOnlyRoots read_only_roots() { return impl()->read_only_roots(); }

  Tagged<HeapObject> AllocateRaw(
      int size, AllocationType allocation,
      AllocationAlignment alignment = kTaggedAligned);

  friend TorqueGeneratedFactory<Impl>;
};

extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
    FactoryBase<Factory>;
extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
    FactoryBase<LocalFactory>;

}  // namespace internal
}  // namespace v8

#endif  // V8_HEAP_FACTORY_BASE_H_