1 // Copyright 2014 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_H_ 6 #define V8_HEAP_FACTORY_H_ 7 8 // Clients of this interface shouldn't depend on lots of heap internals. 9 // Do not include anything from src/heap here! 10 #include "src/builtins/builtins.h" 11 #include "src/common/globals.h" 12 #include "src/execution/messages.h" 13 #include "src/handles/handles.h" 14 #include "src/handles/maybe-handles.h" 15 #include "src/heap/factory-base.h" 16 #include "src/heap/heap.h" 17 #include "src/objects/code.h" 18 #include "src/objects/dictionary.h" 19 #include "src/objects/js-array.h" 20 #include "src/objects/js-regexp.h" 21 #include "src/objects/shared-function-info.h" 22 #include "src/objects/string.h" 23 #include "torque-generated/class-forward-declarations.h" 24 25 namespace v8 { 26 namespace internal { 27 28 // Forward declarations. 29 class AliasedArgumentsEntry; 30 class ObjectBoilerplateDescription; 31 class BasicBlockProfilerData; 32 class BreakPoint; 33 class BreakPointInfo; 34 class CallableTask; 35 class CallbackTask; 36 class CallHandlerInfo; 37 class Expression; 38 class EmbedderDataArray; 39 class ArrayBoilerplateDescription; 40 class CoverageInfo; 41 class DebugInfo; 42 class EnumCache; 43 class FreshlyAllocatedBigInt; 44 class Isolate; 45 class JSArrayBufferView; 46 class JSDataView; 47 class JSGeneratorObject; 48 class JSMap; 49 class JSMapIterator; 50 class JSModuleNamespace; 51 class JSPromise; 52 class JSProxy; 53 class JSSet; 54 class JSSetIterator; 55 class JSTypedArray; 56 class JSWeakMap; 57 class LoadHandler; 58 class NativeContext; 59 class NewFunctionArgs; 60 class PromiseResolveThenableJobTask; 61 class RegExpMatchInfo; 62 class ScriptContextTable; 63 class SourceTextModule; 64 class StackFrameInfo; 65 class StackTraceFrame; 66 class StringSet; 67 class StoreHandler; 68 class SyntheticModule; 69 class TemplateObjectDescription; 70 class WasmCapiFunctionData; 71 class WasmExportedFunctionData; 72 class WasmJSFunctionData; 73 class WeakCell; 74 75 namespace wasm { 76 class ValueType; 77 } // namespace wasm 78 79 enum class SharedFlag : uint8_t; 80 enum class InitializedFlag : uint8_t; 81 82 enum FunctionMode { 83 kWithNameBit = 1 << 0, 84 kWithHomeObjectBit = 1 << 1, 85 kWithWritablePrototypeBit = 1 << 2, 86 kWithReadonlyPrototypeBit = 1 << 3, 87 kWithPrototypeBits = kWithWritablePrototypeBit | kWithReadonlyPrototypeBit, 88 89 // Without prototype. 90 FUNCTION_WITHOUT_PROTOTYPE = 0, 91 METHOD_WITH_NAME = kWithNameBit, 92 METHOD_WITH_HOME_OBJECT = kWithHomeObjectBit, 93 METHOD_WITH_NAME_AND_HOME_OBJECT = kWithNameBit | kWithHomeObjectBit, 94 95 // With writable prototype. 96 FUNCTION_WITH_WRITEABLE_PROTOTYPE = kWithWritablePrototypeBit, 97 FUNCTION_WITH_NAME_AND_WRITEABLE_PROTOTYPE = 98 kWithWritablePrototypeBit | kWithNameBit, 99 FUNCTION_WITH_HOME_OBJECT_AND_WRITEABLE_PROTOTYPE = 100 kWithWritablePrototypeBit | kWithHomeObjectBit, 101 FUNCTION_WITH_NAME_AND_HOME_OBJECT_AND_WRITEABLE_PROTOTYPE = 102 kWithWritablePrototypeBit | kWithNameBit | kWithHomeObjectBit, 103 104 // With readonly prototype. 105 FUNCTION_WITH_READONLY_PROTOTYPE = kWithReadonlyPrototypeBit, 106 FUNCTION_WITH_NAME_AND_READONLY_PROTOTYPE = 107 kWithReadonlyPrototypeBit | kWithNameBit, 108 }; 109 110 enum class NumberCacheMode { kIgnore, kSetOnly, kBoth }; 111 112 // Interface for handle based allocation. 113 class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> { 114 public: 115 inline ReadOnlyRoots read_only_roots(); 116 117 template <typename T> MakeHandle(T obj)118 Handle<T> MakeHandle(T obj) { 119 return handle(obj, isolate()); 120 } 121 122 #include "torque-generated/factory.inc" 123 124 // Avoid the Torque-generated factory function to shadow the one from 125 // FactoryBase. 126 using FactoryBase::NewDescriptorArray; 127 128 Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string, 129 Handle<Object> to_number, const char* type_of, 130 byte kind); 131 132 // Marks self references within code generation. 133 Handle<Oddball> NewSelfReferenceMarker(); 134 135 // Marks references to a function's basic-block usage counters array during 136 // code generation. 137 Handle<Oddball> NewBasicBlockCountersMarker(); 138 139 // Allocates a property array initialized with undefined values. 140 Handle<PropertyArray> NewPropertyArray(int length); 141 // Tries allocating a fixed array initialized with undefined values. 142 // In case of an allocation failure (OOM) an empty handle is returned. 143 // The caller has to manually signal an 144 // v8::internal::Heap::FatalProcessOutOfMemory typically by calling 145 // NewFixedArray as a fallback. 146 V8_WARN_UNUSED_RESULT 147 MaybeHandle<FixedArray> TryNewFixedArray( 148 int length, AllocationType allocation = AllocationType::kYoung); 149 150 // Allocates an uninitialized fixed array. It must be filled by the caller. 151 Handle<FixedArray> NewUninitializedFixedArray(int length); 152 153 // Allocates a closure feedback cell array whose feedback cells are 154 // initialized with undefined values. 155 Handle<ClosureFeedbackCellArray> NewClosureFeedbackCellArray(int num_slots); 156 157 // Allocates a feedback vector whose slots are initialized with undefined 158 // values. 159 Handle<FeedbackVector> NewFeedbackVector( 160 Handle<SharedFunctionInfo> shared, 161 Handle<ClosureFeedbackCellArray> closure_feedback_cell_array); 162 163 // Allocates a clean embedder data array with given capacity. 164 Handle<EmbedderDataArray> NewEmbedderDataArray(int length); 165 166 // Allocate a new fixed double array with hole values. 167 Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles(int size); 168 169 Handle<FrameArray> NewFrameArray(int number_of_frames); 170 171 // Allocates a |NameDictionary| with an internal capacity calculated such that 172 // |at_least_space_for| entries can be added without reallocating. 173 Handle<NameDictionary> NewNameDictionary(int at_least_space_for); 174 175 // Allocates an |OrderedNameDictionary| of the given capacity. This guarantees 176 // that |capacity| entries can be added without reallocating. 177 Handle<OrderedNameDictionary> NewOrderedNameDictionary( 178 int capacity = OrderedNameDictionary::kInitialCapacity); 179 180 Handle<OrderedHashSet> NewOrderedHashSet(); 181 Handle<OrderedHashMap> NewOrderedHashMap(); 182 Handle<SmallOrderedHashSet> NewSmallOrderedHashSet( 183 int capacity = kSmallOrderedHashSetMinCapacity, 184 AllocationType allocation = AllocationType::kYoung); 185 Handle<SmallOrderedHashMap> NewSmallOrderedHashMap( 186 int capacity = kSmallOrderedHashMapMinCapacity, 187 AllocationType allocation = AllocationType::kYoung); 188 Handle<SmallOrderedNameDictionary> NewSmallOrderedNameDictionary( 189 int capacity = kSmallOrderedHashMapMinCapacity, 190 AllocationType allocation = AllocationType::kYoung); 191 192 // Create a new PrototypeInfo struct. 193 Handle<PrototypeInfo> NewPrototypeInfo(); 194 195 // Create a new EnumCache struct. 196 Handle<EnumCache> NewEnumCache(Handle<FixedArray> keys, 197 Handle<FixedArray> indices); 198 199 // Create a new Tuple2 struct. 200 Handle<Tuple2> NewTuple2(Handle<Object> value1, Handle<Object> value2, 201 AllocationType allocation); 202 203 // Create a new PropertyDescriptorObject struct. 204 Handle<PropertyDescriptorObject> NewPropertyDescriptorObject(); 205 206 // Finds the internalized copy for string in the string table. 207 // If not found, a new string is added to the table and returned. 208 Handle<String> InternalizeUtf8String(const Vector<const char>& str); InternalizeUtf8String(const char * str)209 Handle<String> InternalizeUtf8String(const char* str) { 210 return InternalizeUtf8String(CStrVector(str)); 211 } 212 213 // Import InternalizeString overloads from base class. 214 using FactoryBase::InternalizeString; 215 216 Handle<String> InternalizeString(Vector<const char> str, 217 bool convert_encoding = false) { 218 return InternalizeString(Vector<const uint8_t>::cast(str)); 219 } 220 221 template <typename SeqString> 222 Handle<String> InternalizeString(Handle<SeqString>, int from, int length, 223 bool convert_encoding = false); 224 225 // Internalized strings are created in the old generation (data space). 226 inline Handle<String> InternalizeString(Handle<String> string); 227 228 inline Handle<Name> InternalizeName(Handle<Name> name); 229 230 // String creation functions. Most of the string creation functions take 231 // an AllocationType argument to optionally request that they be 232 // allocated in the old generation. Otherwise the default is 233 // AllocationType::kYoung. 234 // 235 // Creates a new String object. There are two String encodings: one-byte and 236 // two-byte. One should choose between the three string factory functions 237 // based on the encoding of the string buffer that the string is 238 // initialized from. 239 // - ...FromOneByte initializes the string from a buffer that is Latin1 240 // encoded (it does not check that the buffer is Latin1 encoded) and 241 // the result will be Latin1 encoded. 242 // - ...FromUtf8 initializes the string from a buffer that is UTF-8 243 // encoded. If the characters are all ASCII characters, the result 244 // will be Latin1 encoded, otherwise it will converted to two-byte. 245 // - ...FromTwoByte initializes the string from a buffer that is two-byte 246 // encoded. If the characters are all Latin1 characters, the result 247 // will be converted to Latin1, otherwise it will be left as two-byte. 248 // 249 // One-byte strings are pretenured when used as keys in the SourceCodeCache. 250 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromOneByte( 251 const Vector<const uint8_t>& str, 252 AllocationType allocation = AllocationType::kYoung); 253 254 template <size_t N> 255 inline Handle<String> NewStringFromStaticChars( 256 const char (&str)[N], 257 AllocationType allocation = AllocationType::kYoung) { 258 DCHECK_EQ(N, strlen(str) + 1); 259 return NewStringFromOneByte(StaticOneByteVector(str), allocation) 260 .ToHandleChecked(); 261 } 262 263 inline Handle<String> NewStringFromAsciiChecked( 264 const char* str, AllocationType allocation = AllocationType::kYoung) { 265 return NewStringFromOneByte(OneByteVector(str), allocation) 266 .ToHandleChecked(); 267 } 268 269 // UTF8 strings are pretenured when used for regexp literal patterns and 270 // flags in the parser. 271 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8( 272 const Vector<const char>& str, 273 AllocationType allocation = AllocationType::kYoung); 274 275 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8SubString( 276 Handle<SeqOneByteString> str, int begin, int end, 277 AllocationType allocation = AllocationType::kYoung); 278 279 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromTwoByte( 280 const Vector<const uc16>& str, 281 AllocationType allocation = AllocationType::kYoung); 282 283 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromTwoByte( 284 const ZoneVector<uc16>* str, 285 AllocationType allocation = AllocationType::kYoung); 286 287 Handle<JSStringIterator> NewJSStringIterator(Handle<String> string); 288 289 Handle<String> NewInternalizedStringImpl(Handle<String> string, int chars, 290 uint32_t hash_field); 291 292 // Compute the matching internalized string map for a string if possible. 293 // Empty handle is returned if string is in new space or not flattened. 294 V8_WARN_UNUSED_RESULT MaybeHandle<Map> InternalizedStringMapForString( 295 Handle<String> string); 296 297 // Creates an internalized copy of an external string. |string| must be 298 // of type StringClass. 299 template <class StringClass> 300 Handle<StringClass> InternalizeExternalString(Handle<String> string); 301 302 // Creates a single character string where the character has given code. 303 // A cache is used for Latin1 codes. 304 Handle<String> LookupSingleCharacterStringFromCode(uint16_t code); 305 306 // Create or lookup a single characters tring made up of a utf16 surrogate 307 // pair. 308 Handle<String> NewSurrogatePairString(uint16_t lead, uint16_t trail); 309 310 // Create a new string object which holds a proper substring of a string. 311 Handle<String> NewProperSubString(Handle<String> str, int begin, int end); 312 313 // Create a new string object which holds a substring of a string. 314 inline Handle<String> NewSubString(Handle<String> str, int begin, int end); 315 316 // Creates a new external String object. There are two String encodings 317 // in the system: one-byte and two-byte. Unlike other String types, it does 318 // not make sense to have a UTF-8 factory function for external strings, 319 // because we cannot change the underlying buffer. Note that these strings 320 // are backed by a string resource that resides outside the V8 heap. 321 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewExternalStringFromOneByte( 322 const ExternalOneByteString::Resource* resource); 323 V8_WARN_UNUSED_RESULT MaybeHandle<String> NewExternalStringFromTwoByte( 324 const ExternalTwoByteString::Resource* resource); 325 326 // Create a symbol in old or read-only space. 327 Handle<Symbol> NewSymbol(AllocationType allocation = AllocationType::kOld); 328 Handle<Symbol> NewPrivateSymbol( 329 AllocationType allocation = AllocationType::kOld); 330 Handle<Symbol> NewPrivateNameSymbol(Handle<String> name); 331 332 // Create a global (but otherwise uninitialized) context. 333 Handle<NativeContext> NewNativeContext(); 334 335 // Create a script context. 336 Handle<Context> NewScriptContext(Handle<NativeContext> outer, 337 Handle<ScopeInfo> scope_info); 338 339 // Create an empty script context table. 340 Handle<ScriptContextTable> NewScriptContextTable(); 341 342 // Create a module context. 343 Handle<Context> NewModuleContext(Handle<SourceTextModule> module, 344 Handle<NativeContext> outer, 345 Handle<ScopeInfo> scope_info); 346 347 // Create a function or eval context. 348 Handle<Context> NewFunctionContext(Handle<Context> outer, 349 Handle<ScopeInfo> scope_info); 350 351 // Create a catch context. 352 Handle<Context> NewCatchContext(Handle<Context> previous, 353 Handle<ScopeInfo> scope_info, 354 Handle<Object> thrown_object); 355 356 // Create a 'with' context. 357 Handle<Context> NewWithContext(Handle<Context> previous, 358 Handle<ScopeInfo> scope_info, 359 Handle<JSReceiver> extension); 360 361 Handle<Context> NewDebugEvaluateContext(Handle<Context> previous, 362 Handle<ScopeInfo> scope_info, 363 Handle<JSReceiver> extension, 364 Handle<Context> wrapped, 365 Handle<StringSet> blocklist); 366 367 // Create a block context. 368 Handle<Context> NewBlockContext(Handle<Context> previous, 369 Handle<ScopeInfo> scope_info); 370 371 // Create a context that's used by builtin functions. 372 // 373 // These are similar to function context but don't have a previous 374 // context or any scope info. These are used to store spec defined 375 // context values. 376 Handle<Context> NewBuiltinContext(Handle<NativeContext> native_context, 377 int length); 378 379 Handle<AliasedArgumentsEntry> NewAliasedArgumentsEntry( 380 int aliased_context_slot); 381 382 Handle<AccessorInfo> NewAccessorInfo(); 383 384 Handle<Script> CloneScript(Handle<Script> script); 385 386 Handle<BreakPointInfo> NewBreakPointInfo(int source_position); 387 Handle<BreakPoint> NewBreakPoint(int id, Handle<String> condition); 388 Handle<StackTraceFrame> NewStackTraceFrame(Handle<FrameArray> frame_array, 389 int index); 390 Handle<StackFrameInfo> NewStackFrameInfo(Handle<FrameArray> frame_array, 391 int index); 392 393 // Allocate various microtasks. 394 Handle<CallableTask> NewCallableTask(Handle<JSReceiver> callable, 395 Handle<Context> context); 396 Handle<CallbackTask> NewCallbackTask(Handle<Foreign> callback, 397 Handle<Foreign> data); 398 Handle<PromiseResolveThenableJobTask> NewPromiseResolveThenableJobTask( 399 Handle<JSPromise> promise_to_resolve, Handle<JSReceiver> thenable, 400 Handle<JSReceiver> then, Handle<Context> context); 401 402 // Foreign objects are pretenured when allocated by the bootstrapper. 403 Handle<Foreign> NewForeign(Address addr); 404 405 Handle<Cell> NewCell(Handle<Object> value); 406 407 Handle<PropertyCell> NewPropertyCell( 408 Handle<Name> name, AllocationType allocation = AllocationType::kOld); 409 410 Handle<FeedbackCell> NewNoClosuresCell(Handle<HeapObject> value); 411 Handle<FeedbackCell> NewOneClosureCell(Handle<HeapObject> value); 412 Handle<FeedbackCell> NewManyClosuresCell(Handle<HeapObject> value); 413 414 Handle<TransitionArray> NewTransitionArray(int number_of_transitions, 415 int slack = 0); 416 417 // Allocate a tenured AllocationSite. Its payload is null. 418 Handle<AllocationSite> NewAllocationSite(bool with_weak_next); 419 420 // Allocates and initializes a new Map. 421 Handle<Map> NewMap(InstanceType type, int instance_size, 422 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 423 int inobject_properties = 0); 424 // Initializes the fields of a newly created Map. Exposed for tests and 425 // heap setup; other code should just call NewMap which takes care of it. 426 Map InitializeMap(Map map, InstanceType type, int instance_size, 427 ElementsKind elements_kind, int inobject_properties); 428 429 // Allocate a block of memory of the given AllocationType (filled with a 430 // filler). Used as a fall-back for generated code when the space is full. 431 Handle<HeapObject> NewFillerObject( 432 int size, bool double_align, AllocationType allocation, 433 AllocationOrigin origin = AllocationOrigin::kRuntime); 434 435 Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function); 436 437 // Returns a deep copy of the JavaScript object. 438 // Properties and elements are copied too. 439 Handle<JSObject> CopyJSObject(Handle<JSObject> object); 440 // Same as above, but also takes an AllocationSite to be appended in an 441 // AllocationMemento. 442 Handle<JSObject> CopyJSObjectWithAllocationSite(Handle<JSObject> object, 443 Handle<AllocationSite> site); 444 445 Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array, 446 Handle<Map> map); 447 448 Handle<FixedArray> CopyFixedArrayAndGrow(Handle<FixedArray> array, 449 int grow_by); 450 451 Handle<WeakArrayList> NewWeakArrayList( 452 int capacity, AllocationType allocation = AllocationType::kYoung); 453 454 Handle<WeakFixedArray> CopyWeakFixedArrayAndGrow(Handle<WeakFixedArray> array, 455 int grow_by); 456 457 Handle<WeakArrayList> CopyWeakArrayListAndGrow( 458 Handle<WeakArrayList> array, int grow_by, 459 AllocationType allocation = AllocationType::kYoung); 460 461 Handle<WeakArrayList> CompactWeakArrayList( 462 Handle<WeakArrayList> array, int new_capacity, 463 AllocationType allocation = AllocationType::kYoung); 464 465 Handle<PropertyArray> CopyPropertyArrayAndGrow(Handle<PropertyArray> array, 466 int grow_by); 467 468 Handle<FixedArray> CopyFixedArrayUpTo( 469 Handle<FixedArray> array, int new_len, 470 AllocationType allocation = AllocationType::kYoung); 471 472 Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); 473 474 // This method expects a COW array in new space, and creates a copy 475 // of it in old space. 476 Handle<FixedArray> CopyAndTenureFixedCOWArray(Handle<FixedArray> array); 477 478 Handle<FixedDoubleArray> CopyFixedDoubleArray(Handle<FixedDoubleArray> array); 479 480 // Creates a new HeapNumber in read-only space if possible otherwise old 481 // space. 482 Handle<HeapNumber> NewHeapNumberForCodeAssembler(double value); 483 484 Handle<JSObject> NewArgumentsObject(Handle<JSFunction> callee, int length); 485 486 // Allocates and initializes a new JavaScript object based on a 487 // constructor. 488 // JS objects are pretenured when allocated by the bootstrapper and 489 // runtime. 490 Handle<JSObject> NewJSObject( 491 Handle<JSFunction> constructor, 492 AllocationType allocation = AllocationType::kYoung); 493 // JSObject without a prototype. 494 Handle<JSObject> NewJSObjectWithNullProto(); 495 496 // Global objects are pretenured and initialized based on a constructor. 497 Handle<JSGlobalObject> NewJSGlobalObject(Handle<JSFunction> constructor); 498 499 // Allocates and initializes a new JavaScript object based on a map. 500 // Passing an allocation site means that a memento will be created that 501 // points to the site. 502 // JS objects are pretenured when allocated by the bootstrapper and 503 // runtime. 504 Handle<JSObject> NewJSObjectFromMap( 505 Handle<Map> map, AllocationType allocation = AllocationType::kYoung, 506 Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()); 507 // Like NewJSObjectFromMap, but includes allocating a properties dictionary. 508 Handle<JSObject> NewSlowJSObjectFromMap( 509 Handle<Map> map, 510 int number_of_slow_properties = NameDictionary::kInitialCapacity, 511 AllocationType allocation = AllocationType::kYoung, 512 Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()); 513 // Calls NewJSObjectFromMap or NewSlowJSObjectFromMap depending on whether the 514 // map is a dictionary map. 515 inline Handle<JSObject> NewFastOrSlowJSObjectFromMap( 516 Handle<Map> map, 517 int number_of_slow_properties = NameDictionary::kInitialCapacity, 518 AllocationType allocation = AllocationType::kYoung, 519 Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()); 520 // Allocates and initializes a new JavaScript object with the given 521 // {prototype} and {properties}. The newly created object will be 522 // in dictionary properties mode. The {elements} can either be the 523 // empty fixed array, in which case the resulting object will have 524 // fast elements, or a NumberDictionary, in which case the resulting 525 // object will have dictionary elements. 526 Handle<JSObject> NewSlowJSObjectWithPropertiesAndElements( 527 Handle<HeapObject> prototype, Handle<NameDictionary> properties, 528 Handle<FixedArrayBase> elements); 529 530 // JS arrays are pretenured when allocated by the parser. 531 532 // Create a JSArray with a specified length and elements initialized 533 // according to the specified mode. 534 Handle<JSArray> NewJSArray( 535 ElementsKind elements_kind, int length, int capacity, 536 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS, 537 AllocationType allocation = AllocationType::kYoung); 538 539 Handle<JSArray> NewJSArray( 540 int capacity, ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 541 AllocationType allocation = AllocationType::kYoung) { 542 if (capacity != 0) { 543 elements_kind = GetHoleyElementsKind(elements_kind); 544 } 545 return NewJSArray(elements_kind, 0, capacity, 546 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, allocation); 547 } 548 549 // Create a JSArray with the given elements. 550 Handle<JSArray> NewJSArrayWithElements( 551 Handle<FixedArrayBase> elements, ElementsKind elements_kind, int length, 552 AllocationType allocation = AllocationType::kYoung); 553 554 inline Handle<JSArray> NewJSArrayWithElements( 555 Handle<FixedArrayBase> elements, 556 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 557 AllocationType allocation = AllocationType::kYoung); 558 559 void NewJSArrayStorage( 560 Handle<JSArray> array, int length, int capacity, 561 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS); 562 563 Handle<JSWeakMap> NewJSWeakMap(); 564 565 Handle<JSGeneratorObject> NewJSGeneratorObject(Handle<JSFunction> function); 566 567 Handle<JSModuleNamespace> NewJSModuleNamespace(); 568 569 Handle<WasmTypeInfo> NewWasmTypeInfo(Address type_address, 570 Handle<Map> parent); 571 572 Handle<SourceTextModule> NewSourceTextModule(Handle<SharedFunctionInfo> code); 573 Handle<SyntheticModule> NewSyntheticModule( 574 Handle<String> module_name, Handle<FixedArray> export_names, 575 v8::Module::SyntheticModuleEvaluationSteps evaluation_steps); 576 577 Handle<JSArrayBuffer> NewJSArrayBuffer( 578 std::shared_ptr<BackingStore> backing_store, 579 AllocationType allocation = AllocationType::kYoung); 580 581 MaybeHandle<JSArrayBuffer> NewJSArrayBufferAndBackingStore( 582 size_t byte_length, InitializedFlag initialized, 583 AllocationType allocation = AllocationType::kYoung); 584 585 Handle<JSArrayBuffer> NewJSSharedArrayBuffer( 586 std::shared_ptr<BackingStore> backing_store); 587 588 static void TypeAndSizeForElementsKind(ElementsKind kind, 589 ExternalArrayType* array_type, 590 size_t* element_size); 591 592 // Creates a new JSTypedArray with the specified buffer. 593 Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type, 594 Handle<JSArrayBuffer> buffer, 595 size_t byte_offset, size_t length); 596 597 Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer, 598 size_t byte_offset, size_t byte_length); 599 600 Handle<JSIteratorResult> NewJSIteratorResult(Handle<Object> value, bool done); 601 Handle<JSAsyncFromSyncIterator> NewJSAsyncFromSyncIterator( 602 Handle<JSReceiver> sync_iterator, Handle<Object> next); 603 604 Handle<JSMap> NewJSMap(); 605 Handle<JSSet> NewJSSet(); 606 607 // Allocates a bound function. 608 MaybeHandle<JSBoundFunction> NewJSBoundFunction( 609 Handle<JSReceiver> target_function, Handle<Object> bound_this, 610 Vector<Handle<Object>> bound_args); 611 612 // Allocates a Harmony proxy. 613 Handle<JSProxy> NewJSProxy(Handle<JSReceiver> target, 614 Handle<JSReceiver> handler); 615 616 // Reinitialize an JSGlobalProxy based on a constructor. The object 617 // must have the same size as objects allocated using the 618 // constructor. The object is reinitialized and behaves as an 619 // object that has been freshly allocated using the constructor. 620 void ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> global, 621 Handle<JSFunction> constructor); 622 623 Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy(int size); 624 625 // Creates a new JSFunction according to the given args. This is the function 626 // you'll probably want to use when creating a JSFunction from the runtime. 627 Handle<JSFunction> NewFunction(const NewFunctionArgs& args); 628 629 // For testing only. Creates a sloppy function without code. 630 Handle<JSFunction> NewFunctionForTest(Handle<String> name); 631 632 // Function creation from SharedFunctionInfo. 633 634 Handle<JSFunction> NewFunctionFromSharedFunctionInfo( 635 Handle<SharedFunctionInfo> function_info, Handle<Context> context, 636 Handle<FeedbackCell> feedback_cell, 637 AllocationType allocation = AllocationType::kOld); 638 639 Handle<JSFunction> NewFunctionFromSharedFunctionInfo( 640 Handle<Map> initial_map, Handle<SharedFunctionInfo> function_info, 641 Handle<Context> context, 642 AllocationType allocation = AllocationType::kOld); 643 644 Handle<JSFunction> NewFunctionFromSharedFunctionInfo( 645 Handle<SharedFunctionInfo> function_info, Handle<Context> context, 646 AllocationType allocation = AllocationType::kOld); 647 648 // The choke-point for JSFunction creation. Handles allocation and 649 // initialization. All other utility methods call into this. 650 Handle<JSFunction> NewFunction( 651 Handle<Map> map, Handle<SharedFunctionInfo> info, Handle<Context> context, 652 AllocationType allocation = AllocationType::kOld); 653 654 // Create an External object for V8's external API. 655 Handle<JSObject> NewExternal(void* value); 656 657 // Creates a new CodeDataContainer for a Code object. 658 Handle<CodeDataContainer> NewCodeDataContainer(int flags, 659 AllocationType allocation); 660 661 // Allocates a new code object and initializes it as the trampoline to the 662 // given off-heap entry point. 663 Handle<Code> NewOffHeapTrampolineFor(Handle<Code> code, 664 Address off_heap_entry); 665 666 Handle<Code> CopyCode(Handle<Code> code); 667 668 Handle<BytecodeArray> CopyBytecodeArray(Handle<BytecodeArray>); 669 670 // Interface for creating error objects. 671 Handle<JSObject> NewError(Handle<JSFunction> constructor, 672 Handle<String> message); 673 674 Handle<Object> NewInvalidStringLengthError(); 675 676 inline Handle<Object> NewURIError(); 677 678 Handle<JSObject> NewError(Handle<JSFunction> constructor, 679 MessageTemplate template_index, 680 Handle<Object> arg0 = Handle<Object>(), 681 Handle<Object> arg1 = Handle<Object>(), 682 Handle<Object> arg2 = Handle<Object>()); 683 684 #define DECLARE_ERROR(NAME) \ 685 Handle<JSObject> New##NAME(MessageTemplate template_index, \ 686 Handle<Object> arg0 = Handle<Object>(), \ 687 Handle<Object> arg1 = Handle<Object>(), \ 688 Handle<Object> arg2 = Handle<Object>()); 689 DECLARE_ERROR(Error) 690 DECLARE_ERROR(EvalError) 691 DECLARE_ERROR(RangeError) 692 DECLARE_ERROR(ReferenceError) 693 DECLARE_ERROR(SyntaxError) 694 DECLARE_ERROR(TypeError) 695 DECLARE_ERROR(WasmCompileError) 696 DECLARE_ERROR(WasmLinkError) 697 DECLARE_ERROR(WasmRuntimeError) 698 #undef DECLARE_ERROR 699 700 Handle<String> NumberToString(Handle<Object> number, 701 NumberCacheMode mode = NumberCacheMode::kBoth); 702 Handle<String> SmiToString(Smi number, 703 NumberCacheMode mode = NumberCacheMode::kBoth); 704 Handle<String> HeapNumberToString( 705 Handle<HeapNumber> number, double value, 706 NumberCacheMode mode = NumberCacheMode::kBoth); 707 708 Handle<String> SizeToString(size_t value, bool check_cache = true); 709 inline Handle<String> Uint32ToString(uint32_t value, 710 bool check_cache = true) { 711 return SizeToString(value, check_cache); 712 } 713 714 #define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name(); 715 ROOT_LIST(ROOT_ACCESSOR) 716 #undef ROOT_ACCESSOR 717 718 // Allocates a new SharedFunctionInfo object. 719 Handle<SharedFunctionInfo> NewSharedFunctionInfoForApiFunction( 720 MaybeHandle<String> maybe_name, 721 Handle<FunctionTemplateInfo> function_template_info, FunctionKind kind); 722 723 Handle<SharedFunctionInfo> NewSharedFunctionInfoForWasmCapiFunction( 724 Handle<WasmCapiFunctionData> data); 725 726 Handle<SharedFunctionInfo> NewSharedFunctionInfoForBuiltin( 727 MaybeHandle<String> name, int builtin_index, 728 FunctionKind kind = kNormalFunction); 729 IsFunctionModeWithPrototype(FunctionMode function_mode)730 static bool IsFunctionModeWithPrototype(FunctionMode function_mode) { 731 return (function_mode & kWithPrototypeBits) != 0; 732 } 733 IsFunctionModeWithWritablePrototype(FunctionMode function_mode)734 static bool IsFunctionModeWithWritablePrototype(FunctionMode function_mode) { 735 return (function_mode & kWithWritablePrototypeBit) != 0; 736 } 737 IsFunctionModeWithName(FunctionMode function_mode)738 static bool IsFunctionModeWithName(FunctionMode function_mode) { 739 return (function_mode & kWithNameBit) != 0; 740 } 741 IsFunctionModeWithHomeObject(FunctionMode function_mode)742 static bool IsFunctionModeWithHomeObject(FunctionMode function_mode) { 743 return (function_mode & kWithHomeObjectBit) != 0; 744 } 745 746 Handle<Map> CreateSloppyFunctionMap( 747 FunctionMode function_mode, MaybeHandle<JSFunction> maybe_empty_function); 748 749 Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode, 750 Handle<JSFunction> empty_function); 751 752 Handle<Map> CreateClassFunctionMap(Handle<JSFunction> empty_function); 753 754 // Allocates a new JSMessageObject object. 755 Handle<JSMessageObject> NewJSMessageObject( 756 MessageTemplate message, Handle<Object> argument, int start_position, 757 int end_position, Handle<SharedFunctionInfo> shared_info, 758 int bytecode_offset, Handle<Script> script, Handle<Object> stack_frames); 759 760 Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared); 761 762 Handle<WasmValue> NewWasmValue(int32_t value_type, Handle<Object> ref); 763 764 // Return a map for given number of properties using the map cache in the 765 // native context. 766 Handle<Map> ObjectLiteralMapFromCache(Handle<NativeContext> native_context, 767 int number_of_properties); 768 769 Handle<LoadHandler> NewLoadHandler( 770 int data_count, AllocationType allocation = AllocationType::kOld); 771 Handle<StoreHandler> NewStoreHandler(int data_count); 772 773 Handle<RegExpMatchInfo> NewRegExpMatchInfo(); 774 775 // Creates a new FixedArray that holds the data associated with the 776 // atom regexp and stores it in the regexp. 777 void SetRegExpAtomData(Handle<JSRegExp> regexp, Handle<String> source, 778 JSRegExp::Flags flags, Handle<Object> match_pattern); 779 780 // Creates a new FixedArray that holds the data associated with the 781 // irregexp regexp and stores it in the regexp. 782 void SetRegExpIrregexpData(Handle<JSRegExp> regexp, Handle<String> source, 783 JSRegExp::Flags flags, int capture_count, 784 uint32_t backtrack_limit); 785 786 // Creates a new FixedArray that holds the data associated with the 787 // experimental regexp and stores it in the regexp. 788 void SetRegExpExperimentalData(Handle<JSRegExp> regexp, Handle<String> source, 789 JSRegExp::Flags flags, int capture_count); 790 791 // Returns the value for a known global constant (a property of the global 792 // object which is neither configurable nor writable) like 'undefined'. 793 // Returns a null handle when the given name is unknown. 794 Handle<Object> GlobalConstantFor(Handle<Name> name); 795 796 // Converts the given ToPrimitive hint to it's string representation. 797 Handle<String> ToPrimitiveHintString(ToPrimitiveHint hint); 798 799 Handle<JSPromise> NewJSPromiseWithoutHook(); 800 Handle<JSPromise> NewJSPromise(); 801 802 Handle<CallHandlerInfo> NewCallHandlerInfo(bool has_no_side_effect = false); 803 NewForTest(Handle<Map> map,AllocationType allocation)804 HeapObject NewForTest(Handle<Map> map, AllocationType allocation) { 805 return New(map, allocation); 806 } 807 808 // Helper class for creating JSFunction objects. 809 class JSFunctionBuilder final { 810 public: 811 JSFunctionBuilder(Isolate* isolate, Handle<SharedFunctionInfo> sfi, 812 Handle<Context> context); 813 814 V8_WARN_UNUSED_RESULT Handle<JSFunction> Build(); 815 set_map(Handle<Map> v)816 JSFunctionBuilder& set_map(Handle<Map> v) { 817 maybe_map_ = v; 818 return *this; 819 } set_allocation_type(AllocationType v)820 JSFunctionBuilder& set_allocation_type(AllocationType v) { 821 allocation_type_ = v; 822 return *this; 823 } set_feedback_cell(Handle<FeedbackCell> v)824 JSFunctionBuilder& set_feedback_cell(Handle<FeedbackCell> v) { 825 maybe_feedback_cell_ = v; 826 return *this; 827 } 828 829 private: 830 void PrepareMap(); 831 void PrepareFeedbackCell(); 832 833 V8_WARN_UNUSED_RESULT Handle<JSFunction> BuildRaw(Handle<Code> code); 834 835 Isolate* const isolate_; 836 Handle<SharedFunctionInfo> sfi_; 837 Handle<Context> context_; 838 MaybeHandle<Map> maybe_map_; 839 MaybeHandle<FeedbackCell> maybe_feedback_cell_; 840 AllocationType allocation_type_ = AllocationType::kOld; 841 842 friend class Factory; 843 }; 844 845 // Allows creation of Code objects. It provides two build methods, one of 846 // which tries to gracefully handle allocation failure. 847 class V8_EXPORT_PRIVATE CodeBuilder final { 848 public: 849 CodeBuilder(Isolate* isolate, const CodeDesc& desc, CodeKind kind); 850 851 // Builds a new code object (fully initialized). All header fields of the 852 // returned object are immutable and the code object is write protected. 853 V8_WARN_UNUSED_RESULT Handle<Code> Build(); 854 // Like Build, builds a new code object. May return an empty handle if the 855 // allocation fails. 856 V8_WARN_UNUSED_RESULT MaybeHandle<Code> TryBuild(); 857 858 // Sets the self-reference object in which a reference to the code object is 859 // stored. This allows generated code to reference its own Code object by 860 // using this handle. set_self_reference(Handle<Object> self_reference)861 CodeBuilder& set_self_reference(Handle<Object> self_reference) { 862 DCHECK(!self_reference.is_null()); 863 self_reference_ = self_reference; 864 return *this; 865 } 866 set_builtin_index(int32_t builtin_index)867 CodeBuilder& set_builtin_index(int32_t builtin_index) { 868 builtin_index_ = builtin_index; 869 return *this; 870 } 871 set_inlined_bytecode_size(uint32_t size)872 CodeBuilder& set_inlined_bytecode_size(uint32_t size) { 873 inlined_bytecode_size_ = size; 874 return *this; 875 } 876 set_source_position_table(Handle<ByteArray> table)877 CodeBuilder& set_source_position_table(Handle<ByteArray> table) { 878 DCHECK(!table.is_null()); 879 source_position_table_ = table; 880 return *this; 881 } 882 set_deoptimization_data(Handle<DeoptimizationData> deopt_data)883 CodeBuilder& set_deoptimization_data( 884 Handle<DeoptimizationData> deopt_data) { 885 DCHECK(!deopt_data.is_null()); 886 deoptimization_data_ = deopt_data; 887 return *this; 888 } 889 set_is_turbofanned()890 CodeBuilder& set_is_turbofanned() { 891 is_turbofanned_ = true; 892 return *this; 893 } 894 set_is_executable(bool executable)895 CodeBuilder& set_is_executable(bool executable) { 896 is_executable_ = executable; 897 return *this; 898 } 899 900 // Indicates the CodeDataContainer should be allocated in read-only space. 901 // As an optimization, if the kind-specific flags match that of a canonical 902 // container, it will be used instead. set_read_only_data_container(int32_t flags)903 CodeBuilder& set_read_only_data_container(int32_t flags) { 904 read_only_data_container_ = true; 905 kind_specific_flags_ = flags; 906 return *this; 907 } 908 set_stack_slots(int stack_slots)909 CodeBuilder& set_stack_slots(int stack_slots) { 910 stack_slots_ = stack_slots; 911 return *this; 912 } 913 set_profiler_data(BasicBlockProfilerData * profiler_data)914 CodeBuilder& set_profiler_data(BasicBlockProfilerData* profiler_data) { 915 profiler_data_ = profiler_data; 916 return *this; 917 } 918 919 private: 920 MaybeHandle<Code> BuildInternal(bool retry_allocation_or_fail); 921 922 Isolate* const isolate_; 923 const CodeDesc& code_desc_; 924 const CodeKind kind_; 925 926 MaybeHandle<Object> self_reference_; 927 int32_t builtin_index_ = Builtins::kNoBuiltinId; 928 uint32_t inlined_bytecode_size_ = 0; 929 int32_t kind_specific_flags_ = 0; 930 Handle<ByteArray> source_position_table_; 931 Handle<DeoptimizationData> deoptimization_data_ = 932 DeoptimizationData::Empty(isolate_); 933 BasicBlockProfilerData* profiler_data_ = nullptr; 934 bool is_executable_ = true; 935 bool read_only_data_container_ = false; 936 bool is_turbofanned_ = false; 937 int stack_slots_ = 0; 938 }; 939 940 private: 941 friend class FactoryBase<Factory>; 942 943 // ------ 944 // Customization points for FactoryBase 945 HeapObject AllocateRaw(int size, AllocationType allocation, 946 AllocationAlignment alignment = kWordAligned); 947 isolate()948 Isolate* isolate() { 949 // Downcast to the privately inherited sub-class using c-style casts to 950 // avoid undefined behavior (as static_cast cannot cast across private 951 // bases). 952 // NOLINTNEXTLINE (google-readability-casting) 953 return (Isolate*)this; // NOLINT(readability/casting) 954 } 955 bool CanAllocateInReadOnlySpace(); 956 bool EmptyStringRootIsInitialized(); 957 958 void AddToScriptList(Handle<Script> shared); 959 // ------ 960 961 HeapObject AllocateRawWithAllocationSite( 962 Handle<Map> map, AllocationType allocation, 963 Handle<AllocationSite> allocation_site); 964 965 Handle<JSArrayBufferView> NewJSArrayBufferView( 966 Handle<Map> map, Handle<FixedArrayBase> elements, 967 Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length); 968 969 // Allocates new context with given map, sets length and initializes the 970 // after-header part with uninitialized values and leaves the context header 971 // uninitialized. 972 Handle<Context> NewContext(Handle<Map> map, int size, 973 int variadic_part_length, 974 AllocationType allocation); 975 976 template <typename T> 977 Handle<T> AllocateSmallOrderedHashTable(Handle<Map> map, int capacity, 978 AllocationType allocation); 979 980 // Creates a heap object based on the map. The fields of the heap object are 981 // not initialized, it's the responsibility of the caller to do that. 982 HeapObject New(Handle<Map> map, AllocationType allocation); 983 984 template <typename T> 985 Handle<T> CopyArrayWithMap(Handle<T> src, Handle<Map> map); 986 template <typename T> 987 Handle<T> CopyArrayAndGrow(Handle<T> src, int grow_by, 988 AllocationType allocation); 989 990 template <bool is_one_byte, typename T> 991 Handle<String> AllocateInternalizedStringImpl(T t, int chars, 992 uint32_t hash_field); 993 994 Handle<String> AllocateTwoByteInternalizedString( 995 const Vector<const uc16>& str, uint32_t hash_field); 996 997 MaybeHandle<String> NewStringFromTwoByte(const uc16* string, int length, 998 AllocationType allocation); 999 1000 // Attempt to find the number in a small cache. If we finds it, return 1001 // the string representation of the number. Otherwise return undefined. 1002 V8_INLINE Handle<Object> NumberToStringCacheGet(Object number, int hash); 1003 1004 // Update the cache with a new number-string pair. 1005 V8_INLINE void NumberToStringCacheSet(Handle<Object> number, int hash, 1006 Handle<String> js_string); 1007 1008 // Creates a new JSArray with the given backing storage. Performs no 1009 // verification of the backing storage because it may not yet be filled. 1010 Handle<JSArray> NewJSArrayWithUnverifiedElements( 1011 Handle<FixedArrayBase> elements, ElementsKind elements_kind, int length, 1012 AllocationType allocation = AllocationType::kYoung); 1013 1014 // Creates the backing storage for a JSArray. This handle must be discarded 1015 // before returning the JSArray reference to code outside Factory, which might 1016 // decide to left-trim the backing store. To avoid unnecessary HandleScopes, 1017 // this method requires capacity greater than zero. 1018 Handle<FixedArrayBase> NewJSArrayStorage( 1019 ElementsKind elements_kind, int capacity, 1020 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS); 1021 1022 void InitializeAllocationMemento(AllocationMemento memento, 1023 AllocationSite allocation_site); 1024 1025 // Initializes a JSObject based on its map. 1026 void InitializeJSObjectFromMap(Handle<JSObject> obj, 1027 Handle<Object> properties, Handle<Map> map); 1028 // Initializes JSObject body starting at given offset. 1029 void InitializeJSObjectBody(Handle<JSObject> obj, Handle<Map> map, 1030 int start_offset); 1031 1032 private: 1033 Handle<WeakArrayList> NewUninitializedWeakArrayList( 1034 int capacity, AllocationType allocation = AllocationType::kYoung); 1035 }; 1036 1037 // Utility class to simplify argument handling around JSFunction creation. 1038 class NewFunctionArgs final { 1039 public: 1040 static NewFunctionArgs ForWasm( 1041 Handle<String> name, 1042 Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map); 1043 static NewFunctionArgs ForWasm(Handle<String> name, 1044 Handle<WasmJSFunctionData> js_function_data, 1045 Handle<Map> map); 1046 V8_EXPORT_PRIVATE static NewFunctionArgs ForBuiltin(Handle<String> name, 1047 Handle<Map> map, 1048 int builtin_id); 1049 static NewFunctionArgs ForFunctionWithoutCode(Handle<String> name, 1050 Handle<Map> map, 1051 LanguageMode language_mode); 1052 static NewFunctionArgs ForBuiltinWithPrototype( 1053 Handle<String> name, Handle<HeapObject> prototype, InstanceType type, 1054 int instance_size, int inobject_properties, int builtin_id, 1055 MutableMode prototype_mutability); 1056 static NewFunctionArgs ForBuiltinWithoutPrototype(Handle<String> name, 1057 int builtin_id, 1058 LanguageMode language_mode); 1059 1060 Handle<Map> GetMap(Isolate* isolate) const; 1061 1062 private: 1063 NewFunctionArgs() = default; // Use the static factory constructors. 1064 1065 void SetShouldCreateAndSetInitialMap(); 1066 void SetShouldSetPrototype(); 1067 void SetShouldSetLanguageMode(); 1068 1069 // Sentinel value. 1070 static const int kUninitialized = -1; 1071 1072 Handle<String> name_; 1073 MaybeHandle<Map> maybe_map_; 1074 MaybeHandle<Struct> maybe_wasm_function_data_; 1075 1076 bool should_create_and_set_initial_map_ = false; 1077 InstanceType type_; 1078 int instance_size_ = kUninitialized; 1079 int inobject_properties_ = kUninitialized; 1080 1081 bool should_set_prototype_ = false; 1082 MaybeHandle<HeapObject> maybe_prototype_; 1083 1084 bool should_set_language_mode_ = false; 1085 LanguageMode language_mode_; 1086 1087 int maybe_builtin_id_ = kUninitialized; 1088 1089 MutableMode prototype_mutability_; 1090 1091 friend class Factory; 1092 }; 1093 1094 } // namespace internal 1095 } // namespace v8 1096 1097 #endif // V8_HEAP_FACTORY_H_ 1098