1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_FACTORY_H_ 29 #define V8_FACTORY_H_ 30 31 #include "globals.h" 32 #include "handles.h" 33 #include "heap.h" 34 35 namespace v8 { 36 namespace internal { 37 38 // Interface for handle based allocation. 39 40 class Factory { 41 public: 42 // Allocate a new boxed value. 43 Handle<Box> NewBox( 44 Handle<Object> value, 45 PretenureFlag pretenure = NOT_TENURED); 46 47 // Allocate a new uninitialized fixed array. 48 Handle<FixedArray> NewFixedArray( 49 int size, 50 PretenureFlag pretenure = NOT_TENURED); 51 52 // Allocate a new fixed array with non-existing entries (the hole). 53 Handle<FixedArray> NewFixedArrayWithHoles( 54 int size, 55 PretenureFlag pretenure = NOT_TENURED); 56 57 // Allocate a new uninitialized fixed double array. 58 Handle<FixedDoubleArray> NewFixedDoubleArray( 59 int size, 60 PretenureFlag pretenure = NOT_TENURED); 61 62 Handle<SeededNumberDictionary> NewSeededNumberDictionary( 63 int at_least_space_for); 64 65 Handle<UnseededNumberDictionary> NewUnseededNumberDictionary( 66 int at_least_space_for); 67 68 Handle<NameDictionary> NewNameDictionary(int at_least_space_for); 69 70 Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for); 71 72 Handle<ObjectHashTable> NewObjectHashTable(int at_least_space_for); 73 74 Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors, 75 int slack = 0); 76 Handle<DeoptimizationInputData> NewDeoptimizationInputData( 77 int deopt_entry_count, 78 PretenureFlag pretenure); 79 Handle<DeoptimizationOutputData> NewDeoptimizationOutputData( 80 int deopt_entry_count, 81 PretenureFlag pretenure); 82 // Allocates a pre-tenured empty AccessorPair. 83 Handle<AccessorPair> NewAccessorPair(); 84 85 Handle<TypeFeedbackInfo> NewTypeFeedbackInfo(); 86 87 Handle<String> InternalizeUtf8String(Vector<const char> str); 88 Handle<String> InternalizeUtf8String(const char* str) { 89 return InternalizeUtf8String(CStrVector(str)); 90 } 91 Handle<String> InternalizeString(Handle<String> str); 92 Handle<String> InternalizeOneByteString(Vector<const uint8_t> str); 93 Handle<String> InternalizeOneByteString(Handle<SeqOneByteString>, 94 int from, 95 int length); 96 Handle<String> InternalizeTwoByteString(Vector<const uc16> str); 97 98 99 // String creation functions. Most of the string creation functions take 100 // a Heap::PretenureFlag argument to optionally request that they be 101 // allocated in the old generation. The pretenure flag defaults to 102 // DONT_TENURE. 103 // 104 // Creates a new String object. There are two String encodings: ASCII and 105 // two byte. One should choose between the three string factory functions 106 // based on the encoding of the string buffer that the string is 107 // initialized from. 108 // - ...FromAscii initializes the string from a buffer that is ASCII 109 // encoded (it does not check that the buffer is ASCII encoded) and 110 // the result will be ASCII encoded. 111 // - ...FromUtf8 initializes the string from a buffer that is UTF-8 112 // encoded. If the characters are all single-byte characters, the 113 // result will be ASCII encoded, otherwise it will converted to two 114 // byte. 115 // - ...FromTwoByte initializes the string from a buffer that is two 116 // byte encoded. If the characters are all single-byte characters, 117 // the result will be converted to ASCII, otherwise it will be left as 118 // two byte. 119 // 120 // ASCII strings are pretenured when used as keys in the SourceCodeCache. 121 Handle<String> NewStringFromOneByte( 122 Vector<const uint8_t> str, 123 PretenureFlag pretenure = NOT_TENURED); 124 // TODO(dcarney): remove this function. 125 inline Handle<String> NewStringFromAscii( 126 Vector<const char> str, 127 PretenureFlag pretenure = NOT_TENURED) { 128 return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure); 129 } 130 131 // UTF8 strings are pretenured when used for regexp literal patterns and 132 // flags in the parser. 133 Handle<String> NewStringFromUtf8( 134 Vector<const char> str, 135 PretenureFlag pretenure = NOT_TENURED); 136 137 Handle<String> NewStringFromTwoByte( 138 Vector<const uc16> str, 139 PretenureFlag pretenure = NOT_TENURED); 140 141 // Allocates and partially initializes an ASCII or TwoByte String. The 142 // characters of the string are uninitialized. Currently used in regexp code 143 // only, where they are pretenured. 144 Handle<SeqOneByteString> NewRawOneByteString( 145 int length, 146 PretenureFlag pretenure = NOT_TENURED); 147 Handle<SeqTwoByteString> NewRawTwoByteString( 148 int length, 149 PretenureFlag pretenure = NOT_TENURED); 150 151 // Create a new cons string object which consists of a pair of strings. 152 Handle<String> NewConsString(Handle<String> first, 153 Handle<String> second); 154 155 // Create a new sequential string containing the concatenation of the inputs. 156 Handle<String> NewFlatConcatString(Handle<String> first, 157 Handle<String> second); 158 159 // Create a new string object which holds a substring of a string. 160 Handle<String> NewSubString(Handle<String> str, 161 int begin, 162 int end); 163 164 // Create a new string object which holds a proper substring of a string. 165 Handle<String> NewProperSubString(Handle<String> str, 166 int begin, 167 int end); 168 169 // Creates a new external String object. There are two String encodings 170 // in the system: ASCII and two byte. Unlike other String types, it does 171 // not make sense to have a UTF-8 factory function for external strings, 172 // because we cannot change the underlying buffer. 173 Handle<String> NewExternalStringFromAscii( 174 const ExternalAsciiString::Resource* resource); 175 Handle<String> NewExternalStringFromTwoByte( 176 const ExternalTwoByteString::Resource* resource); 177 178 // Create a symbol. 179 Handle<Symbol> NewSymbol(); 180 181 // Create a global (but otherwise uninitialized) context. 182 Handle<Context> NewNativeContext(); 183 184 // Create a global context. 185 Handle<Context> NewGlobalContext(Handle<JSFunction> function, 186 Handle<ScopeInfo> scope_info); 187 188 // Create a module context. 189 Handle<Context> NewModuleContext(Handle<ScopeInfo> scope_info); 190 191 // Create a function context. 192 Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function); 193 194 // Create a catch context. 195 Handle<Context> NewCatchContext(Handle<JSFunction> function, 196 Handle<Context> previous, 197 Handle<String> name, 198 Handle<Object> thrown_object); 199 200 // Create a 'with' context. 201 Handle<Context> NewWithContext(Handle<JSFunction> function, 202 Handle<Context> previous, 203 Handle<JSObject> extension); 204 205 // Create a block context. 206 Handle<Context> NewBlockContext(Handle<JSFunction> function, 207 Handle<Context> previous, 208 Handle<ScopeInfo> scope_info); 209 210 // Return the internalized version of the passed in string. 211 Handle<String> InternalizedStringFromString(Handle<String> value); 212 213 // Allocate a new struct. The struct is pretenured (allocated directly in 214 // the old generation). 215 Handle<Struct> NewStruct(InstanceType type); 216 217 Handle<DeclaredAccessorDescriptor> NewDeclaredAccessorDescriptor(); 218 219 Handle<DeclaredAccessorInfo> NewDeclaredAccessorInfo(); 220 221 Handle<ExecutableAccessorInfo> NewExecutableAccessorInfo(); 222 223 Handle<Script> NewScript(Handle<String> source); 224 225 // Foreign objects are pretenured when allocated by the bootstrapper. 226 Handle<Foreign> NewForeign(Address addr, 227 PretenureFlag pretenure = NOT_TENURED); 228 229 // Allocate a new foreign object. The foreign is pretenured (allocated 230 // directly in the old generation). 231 Handle<Foreign> NewForeign(const AccessorDescriptor* foreign); 232 233 Handle<ByteArray> NewByteArray(int length, 234 PretenureFlag pretenure = NOT_TENURED); 235 236 Handle<ExternalArray> NewExternalArray( 237 int length, 238 ExternalArrayType array_type, 239 void* external_pointer, 240 PretenureFlag pretenure = NOT_TENURED); 241 242 Handle<Cell> NewCell(Handle<Object> value); 243 244 Handle<PropertyCell> NewPropertyCell(Handle<Object> value); 245 246 Handle<AllocationSite> NewAllocationSite(); 247 248 Handle<Map> NewMap( 249 InstanceType type, 250 int instance_size, 251 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND); 252 253 Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function); 254 255 Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map); 256 257 // Copy the map adding more inobject properties if possible without 258 // overflowing the instance size. 259 Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props); 260 Handle<Map> CopyMap(Handle<Map> map); 261 262 Handle<Map> GetElementsTransitionMap(Handle<JSObject> object, 263 ElementsKind elements_kind); 264 265 Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); 266 267 Handle<FixedArray> CopySizeFixedArray(Handle<FixedArray> array, 268 int new_length); 269 270 Handle<FixedDoubleArray> CopyFixedDoubleArray( 271 Handle<FixedDoubleArray> array); 272 273 // Numbers (e.g. literals) are pretenured by the parser. 274 Handle<Object> NewNumber(double value, 275 PretenureFlag pretenure = NOT_TENURED); 276 277 Handle<Object> NewNumberFromInt(int32_t value, 278 PretenureFlag pretenure = NOT_TENURED); 279 Handle<Object> NewNumberFromUint(uint32_t value, 280 PretenureFlag pretenure = NOT_TENURED); 281 inline Handle<Object> NewNumberFromSize(size_t value, 282 PretenureFlag pretenure = NOT_TENURED); 283 Handle<HeapNumber> NewHeapNumber(double value, 284 PretenureFlag pretenure = NOT_TENURED); 285 286 287 // These objects are used by the api to create env-independent data 288 // structures in the heap. 289 Handle<JSObject> NewNeanderObject(); 290 291 Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length); 292 293 // JS objects are pretenured when allocated by the bootstrapper and 294 // runtime. 295 Handle<JSObject> NewJSObject(Handle<JSFunction> constructor, 296 PretenureFlag pretenure = NOT_TENURED); 297 298 // Global objects are pretenured. 299 Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor); 300 301 // JS objects are pretenured when allocated by the bootstrapper and 302 // runtime. 303 Handle<JSObject> NewJSObjectFromMap(Handle<Map> map, 304 PretenureFlag pretenure = NOT_TENURED, 305 bool allocate_properties = true); 306 307 Handle<JSObject> NewJSObjectFromMapForDeoptimizer( 308 Handle<Map> map, PretenureFlag pretenure = NOT_TENURED); 309 310 // JS modules are pretenured. 311 Handle<JSModule> NewJSModule(Handle<Context> context, 312 Handle<ScopeInfo> scope_info); 313 314 // JS arrays are pretenured when allocated by the parser. 315 Handle<JSArray> NewJSArray( 316 int capacity, 317 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 318 PretenureFlag pretenure = NOT_TENURED); 319 320 Handle<JSArray> NewJSArrayWithElements( 321 Handle<FixedArrayBase> elements, 322 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 323 PretenureFlag pretenure = NOT_TENURED); 324 325 void SetElementsCapacityAndLength(Handle<JSArray> array, 326 int capacity, 327 int length); 328 329 void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements); 330 331 void EnsureCanContainHeapObjectElements(Handle<JSArray> array); 332 void EnsureCanContainElements(Handle<JSArray> array, 333 Handle<FixedArrayBase> elements, 334 uint32_t length, 335 EnsureElementsMode mode); 336 337 Handle<JSArrayBuffer> NewJSArrayBuffer(); 338 339 Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type); 340 341 Handle<JSDataView> NewJSDataView(); 342 343 Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype); 344 345 // Change the type of the argument into a JS object/function and reinitialize. 346 void BecomeJSObject(Handle<JSReceiver> object); 347 void BecomeJSFunction(Handle<JSReceiver> object); 348 349 void SetIdentityHash(Handle<JSObject> object, Smi* hash); 350 351 Handle<JSFunction> NewFunction(Handle<String> name, 352 Handle<Object> prototype); 353 354 Handle<JSFunction> NewFunctionWithoutPrototype( 355 Handle<String> name, 356 LanguageMode language_mode); 357 358 Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global); 359 360 Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo( 361 Handle<SharedFunctionInfo> function_info, 362 Handle<Map> function_map, 363 PretenureFlag pretenure); 364 365 Handle<JSFunction> NewFunctionFromSharedFunctionInfo( 366 Handle<SharedFunctionInfo> function_info, 367 Handle<Context> context, 368 PretenureFlag pretenure = TENURED); 369 370 Handle<ScopeInfo> NewScopeInfo(int length); 371 372 Handle<JSObject> NewExternal(void* value); 373 374 Handle<Code> NewCode(const CodeDesc& desc, 375 Code::Flags flags, 376 Handle<Object> self_reference, 377 bool immovable = false, 378 bool crankshafted = false); 379 380 Handle<Code> CopyCode(Handle<Code> code); 381 382 Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info); 383 384 Handle<Object> ToObject(Handle<Object> object); 385 Handle<Object> ToObject(Handle<Object> object, 386 Handle<Context> native_context); 387 388 // Interface for creating error objects. 389 390 Handle<Object> NewError(const char* maker, const char* message, 391 Handle<JSArray> args); 392 Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args); 393 Handle<Object> NewError(const char* maker, const char* message, 394 Vector< Handle<Object> > args); 395 Handle<Object> NewError(const char* message, 396 Vector< Handle<Object> > args); 397 Handle<Object> NewError(Handle<String> message); 398 Handle<Object> NewError(const char* constructor, 399 Handle<String> message); 400 401 Handle<Object> NewTypeError(const char* message, 402 Vector< Handle<Object> > args); 403 Handle<Object> NewTypeError(Handle<String> message); 404 405 Handle<Object> NewRangeError(const char* message, 406 Vector< Handle<Object> > args); 407 Handle<Object> NewRangeError(Handle<String> message); 408 409 Handle<Object> NewSyntaxError(const char* message, Handle<JSArray> args); 410 Handle<Object> NewSyntaxError(Handle<String> message); 411 412 Handle<Object> NewReferenceError(const char* message, 413 Vector< Handle<Object> > args); 414 Handle<Object> NewReferenceError(Handle<String> message); 415 416 Handle<Object> NewEvalError(const char* message, 417 Vector< Handle<Object> > args); 418 419 420 Handle<JSFunction> NewFunction(Handle<String> name, 421 InstanceType type, 422 int instance_size, 423 Handle<Code> code, 424 bool force_initial_map); 425 426 Handle<JSFunction> NewFunction(Handle<Map> function_map, 427 Handle<SharedFunctionInfo> shared, Handle<Object> prototype); 428 429 430 Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name, 431 InstanceType type, 432 int instance_size, 433 Handle<JSObject> prototype, 434 Handle<Code> code, 435 bool force_initial_map); 436 437 Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name, 438 Handle<Code> code); 439 440 Handle<String> NumberToString(Handle<Object> number); 441 Handle<String> Uint32ToString(uint32_t value); 442 443 enum ApiInstanceType { 444 JavaScriptObject, 445 InnerGlobalObject, 446 OuterGlobalObject 447 }; 448 449 Handle<JSFunction> CreateApiFunction( 450 Handle<FunctionTemplateInfo> data, 451 ApiInstanceType type = JavaScriptObject); 452 453 Handle<JSFunction> InstallMembers(Handle<JSFunction> function); 454 455 // Installs interceptors on the instance. 'desc' is a function template, 456 // and instance is an object instance created by the function of this 457 // function template. 458 void ConfigureInstance(Handle<FunctionTemplateInfo> desc, 459 Handle<JSObject> instance, 460 bool* pending_exception); 461 462 #define ROOT_ACCESSOR(type, name, camel_name) \ 463 inline Handle<type> name() { \ 464 return Handle<type>(BitCast<type**>( \ 465 &isolate()->heap()->roots_[Heap::k##camel_name##RootIndex])); \ 466 } 467 ROOT_LIST(ROOT_ACCESSOR) 468 #undef ROOT_ACCESSOR_ACCESSOR 469 470 #define STRING_ACCESSOR(name, str) \ 471 inline Handle<String> name() { \ 472 return Handle<String>(BitCast<String**>( \ 473 &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \ 474 } 475 INTERNALIZED_STRING_LIST(STRING_ACCESSOR) 476 #undef STRING_ACCESSOR 477 478 Handle<String> hidden_string() { 479 return Handle<String>(&isolate()->heap()->hidden_string_); 480 } 481 482 Handle<SharedFunctionInfo> NewSharedFunctionInfo( 483 Handle<String> name, 484 int number_of_literals, 485 bool is_generator, 486 Handle<Code> code, 487 Handle<ScopeInfo> scope_info); 488 Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name); 489 490 Handle<JSMessageObject> NewJSMessageObject( 491 Handle<String> type, 492 Handle<JSArray> arguments, 493 int start_position, 494 int end_position, 495 Handle<Object> script, 496 Handle<Object> stack_trace, 497 Handle<Object> stack_frames); 498 499 Handle<SeededNumberDictionary> DictionaryAtNumberPut( 500 Handle<SeededNumberDictionary>, 501 uint32_t key, 502 Handle<Object> value); 503 504 Handle<UnseededNumberDictionary> DictionaryAtNumberPut( 505 Handle<UnseededNumberDictionary>, 506 uint32_t key, 507 Handle<Object> value); 508 509 #ifdef ENABLE_DEBUGGER_SUPPORT 510 Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared); 511 #endif 512 513 // Return a map using the map cache in the native context. 514 // The key the an ordered set of property names. 515 Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context, 516 Handle<FixedArray> keys); 517 518 // Creates a new FixedArray that holds the data associated with the 519 // atom regexp and stores it in the regexp. 520 void SetRegExpAtomData(Handle<JSRegExp> regexp, 521 JSRegExp::Type type, 522 Handle<String> source, 523 JSRegExp::Flags flags, 524 Handle<Object> match_pattern); 525 526 // Creates a new FixedArray that holds the data associated with the 527 // irregexp regexp and stores it in the regexp. 528 void SetRegExpIrregexpData(Handle<JSRegExp> regexp, 529 JSRegExp::Type type, 530 Handle<String> source, 531 JSRegExp::Flags flags, 532 int capture_count); 533 534 // Returns the value for a known global constant (a property of the global 535 // object which is neither configurable nor writable) like 'undefined'. 536 // Returns a null handle when the given name is unknown. 537 Handle<Object> GlobalConstantFor(Handle<String> name); 538 539 // Converts the given boolean condition to JavaScript boolean value. 540 Handle<Object> ToBoolean(bool value); 541 542 private: 543 Isolate* isolate() { return reinterpret_cast<Isolate*>(this); } 544 545 Handle<JSFunction> NewFunctionHelper(Handle<String> name, 546 Handle<Object> prototype); 547 548 Handle<JSFunction> NewFunctionWithoutPrototypeHelper( 549 Handle<String> name, 550 LanguageMode language_mode); 551 552 // Create a new map cache. 553 Handle<MapCache> NewMapCache(int at_least_space_for); 554 555 // Update the map cache in the native context with (keys, map) 556 Handle<MapCache> AddToMapCache(Handle<Context> context, 557 Handle<FixedArray> keys, 558 Handle<Map> map); 559 }; 560 561 562 Handle<Object> Factory::NewNumberFromSize(size_t value, 563 PretenureFlag pretenure) { 564 if (Smi::IsValid(static_cast<intptr_t>(value))) { 565 return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)), 566 isolate()); 567 } else { 568 return NewNumber(static_cast<double>(value), pretenure); 569 } 570 } 571 572 573 // Used to "safely" transition from pointer-based runtime code to Handle-based 574 // runtime code. When a GC happens during the called Handle-based code, a 575 // failure object is returned to the pointer-based code to cause it abort and 576 // re-trigger a gc of it's own. Since this double-gc will cause the Handle-based 577 // code to be called twice, it must be idempotent. 578 class IdempotentPointerToHandleCodeTrampoline { 579 public: 580 explicit IdempotentPointerToHandleCodeTrampoline(Isolate* isolate) 581 : isolate_(isolate) {} 582 583 template<typename R> 584 MUST_USE_RESULT MaybeObject* Call(R (*function)()) { 585 int collections = isolate_->heap()->gc_count(); 586 (*function)(); 587 return (collections == isolate_->heap()->gc_count()) 588 ? isolate_->heap()->true_value() 589 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 590 } 591 592 template<typename R> 593 MUST_USE_RESULT MaybeObject* CallWithReturnValue(R (*function)()) { 594 int collections = isolate_->heap()->gc_count(); 595 Object* result = (*function)(); 596 return (collections == isolate_->heap()->gc_count()) 597 ? result 598 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 599 } 600 601 template<typename R, typename P1> 602 MUST_USE_RESULT MaybeObject* Call(R (*function)(P1), P1 p1) { 603 int collections = isolate_->heap()->gc_count(); 604 (*function)(p1); 605 return (collections == isolate_->heap()->gc_count()) 606 ? isolate_->heap()->true_value() 607 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 608 } 609 610 template<typename R, typename P1> 611 MUST_USE_RESULT MaybeObject* CallWithReturnValue( 612 R (*function)(P1), 613 P1 p1) { 614 int collections = isolate_->heap()->gc_count(); 615 Object* result = (*function)(p1); 616 return (collections == isolate_->heap()->gc_count()) 617 ? result 618 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 619 } 620 621 template<typename R, typename P1, typename P2> 622 MUST_USE_RESULT MaybeObject* Call( 623 R (*function)(P1, P2), 624 P1 p1, 625 P2 p2) { 626 int collections = isolate_->heap()->gc_count(); 627 (*function)(p1, p2); 628 return (collections == isolate_->heap()->gc_count()) 629 ? isolate_->heap()->true_value() 630 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 631 } 632 633 template<typename R, typename P1, typename P2> 634 MUST_USE_RESULT MaybeObject* CallWithReturnValue( 635 R (*function)(P1, P2), 636 P1 p1, 637 P2 p2) { 638 int collections = isolate_->heap()->gc_count(); 639 Object* result = (*function)(p1, p2); 640 return (collections == isolate_->heap()->gc_count()) 641 ? result 642 : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); 643 } 644 645 private: 646 Isolate* isolate_; 647 }; 648 649 650 } } // namespace v8::internal 651 652 #endif // V8_FACTORY_H_ 653