| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "ic-inl.h" | 33 #include "ic-inl.h" |
| 34 | 34 |
| 35 namespace v8 { namespace internal { | 35 namespace v8 { namespace internal { |
| 36 | 36 |
| 37 // ---------------------------------------------------------------------------- | 37 // ---------------------------------------------------------------------------- |
| 38 // Support macros for defining builtins in C. | 38 // Support macros for defining builtins in C. |
| 39 // ---------------------------------------------------------------------------- | 39 // ---------------------------------------------------------------------------- |
| 40 // | 40 // |
| 41 // A builtin function is defined by writing: | 41 // A builtin function is defined by writing: |
| 42 // | 42 // |
| 43 // BUILTIN_<n>(name, ...) | 43 // BUILTIN(name) { |
| 44 // { | |
| 45 // ... | 44 // ... |
| 46 // } | 45 // } |
| 47 // BUILTIN_END | 46 // BUILTIN_END |
| 48 // | 47 // |
| 49 // where <n> is the number of arguments (not counting the receiver). The | 48 // In the body of the builtin function, the variable 'receiver' is visible. |
| 50 // names of the arguments must be listed after the name in the declaration. | 49 // The arguments can be accessed through: |
| 51 // In the body of the builtin function, the variables 'env' and 'receiver' | |
| 52 // are visible. The arguments can be accessed through: | |
| 53 // | 50 // |
| 54 // BUILTIN_ARG(0): Receiver (also available as 'receiver') | 51 // BUILTIN_ARG(0): Receiver (also available as 'receiver') |
| 55 // BUILTIN_ARG(1): First argument | 52 // BUILTIN_ARG(1): First argument |
| 56 // ... | 53 // ... |
| 57 // BUILTIN_ARG(n): Last argument | 54 // BUILTIN_ARG(n): Last argument |
| 58 // | 55 // |
| 59 // and they evaluate to undefined values if too few arguments were | 56 // and they evaluate to undefined values if too few arguments were |
| 60 // passed to the builtin function invocation. | 57 // passed to the builtin function invocation. |
| 61 // | 58 // |
| 62 // __argc__ is the number of arguments including the receiver. | 59 // __argc__ is the number of arguments including the receiver. |
| 63 // ---------------------------------------------------------------------------- | 60 // ---------------------------------------------------------------------------- |
| 64 | 61 |
| 65 | 62 |
| 66 // TODO(1238487): This is not okay. We need to get rid of this macro | 63 // TODO(1238487): We should consider passing whether or not the |
| 67 // and start calling the builtins in a more direct way. Looking at the | 64 // builtin was invoked as a constructor as part of the |
| 68 // stack frames for all builtin invocations comes with a pretty | 65 // arguments. Maybe we also want to pass the called function? |
| 69 // significant performance penalty. | |
| 70 #define BUILTIN(name) \ | 66 #define BUILTIN(name) \ |
| 71 static Object* Builtin_##name(int __argc__, \ | |
| 72 Object** __argv__) { \ | |
| 73 Handle<Object> receiver(&__argv__[0]); \ | |
| 74 bool is_construct = false; \ | |
| 75 USE(__argc__); \ | |
| 76 USE(__argv__); \ | |
| 77 { StackFrameIterator it; \ | |
| 78 ASSERT(it.frame()->is_exit()); \ | |
| 79 it.Advance(); \ | |
| 80 StackFrame::Type type = it.frame()->type(); \ | |
| 81 if (type == StackFrame::INTERNAL) { \ | |
| 82 InternalFrame* frame = InternalFrame::cast(it.frame()); \ | |
| 83 is_construct = frame->is_construct_trampoline(); \ | |
| 84 } else if (type == StackFrame::ARGUMENTS_ADAPTOR) { \ | |
| 85 ArgumentsAdaptorFrame* frame = \ | |
| 86 ArgumentsAdaptorFrame::cast(it.frame()); \ | |
| 87 /* __argc__ includes the receiver. */ \ | |
| 88 __argc__ = frame->GetProvidedParametersCount() + 1; \ | |
| 89 __argv__ = reinterpret_cast<Object**>(frame->pp()) - 1; \ | |
| 90 it.Advance(); \ | |
| 91 is_construct = \ | |
| 92 it.frame()->is_internal() && \ | |
| 93 InternalFrame::cast(it.frame())->is_construct_trampoline(); \ | |
| 94 } \ | |
| 95 } | |
| 96 | |
| 97 | |
| 98 // We're transitioning to a much simpler builtins framework where all | |
| 99 // builtins are called *without* arguments adaption. For now, only a | |
| 100 // few of the builtins have been rewritten to support this and they | |
| 101 // all use the NEW_BUILTIN macro instead of plain old BUILTIN. | |
| 102 #define NEW_BUILTIN(name) \ | |
| 103 static Object* Builtin_##name(int __argc__, Object** __argv__) { \ | 67 static Object* Builtin_##name(int __argc__, Object** __argv__) { \ |
| 104 Handle<Object> receiver(&__argv__[0]); | 68 Handle<Object> receiver(&__argv__[0]); |
| 105 | 69 |
| 106 | 70 |
| 107 // Use an inline function to avoid evaluating the index (n) more than | 71 // Use an inline function to avoid evaluating the index (n) more than |
| 108 // once in the BUILTIN_ARG macro. | 72 // once in the BUILTIN_ARG macro. |
| 109 static inline Object* __builtin_arg__(int n, int argc, Object** argv) { | 73 static inline Object* __builtin_arg__(int n, int argc, Object** argv) { |
| 110 ASSERT(n >= 0); | 74 ASSERT(n >= 0); |
| 111 return (argc > n) ? argv[-n] : Heap::undefined_value(); | 75 return (argc > n) ? argv[-n] : Heap::undefined_value(); |
| 112 } | 76 } |
| 113 | 77 |
| 114 | 78 |
| 115 // NOTE: Argument 0 is the receiver. The first 'real' argument is | 79 // NOTE: Argument 0 is the receiver. The first 'real' argument is |
| 116 // argument 1 - BUILTIN_ARG(1). | 80 // argument 1 - BUILTIN_ARG(1). |
| 117 #define BUILTIN_ARG(n) (__builtin_arg__(n, __argc__, __argv__)) | 81 #define BUILTIN_ARG(n) (__builtin_arg__(n, __argc__, __argv__)) |
| 118 | 82 |
| 119 | 83 |
| 120 #define BUILTIN_END \ | 84 #define BUILTIN_END \ |
| 121 return Heap::undefined_value(); \ | 85 return Heap::undefined_value(); \ |
| 122 } | 86 } |
| 123 | 87 |
| 124 | 88 |
| 89 // TODO(1238487): Get rid of this function that determines if the |
| 90 // builtin is called as a constructor. This may be a somewhat slow |
| 91 // operation due to the stack frame iteration. |
| 92 static inline bool CalledAsConstructor() { |
| 93 StackFrameIterator it; |
| 94 ASSERT(it.frame()->is_exit()); |
| 95 it.Advance(); |
| 96 StackFrame* frame = it.frame(); |
| 97 return frame->is_internal() && |
| 98 InternalFrame::cast(frame)->is_construct_trampoline(); |
| 99 } |
| 100 |
| 101 |
| 125 // ---------------------------------------------------------------------------- | 102 // ---------------------------------------------------------------------------- |
| 126 | 103 |
| 127 | 104 |
| 128 int Builtins::construct_call_pc_offset_ = 0; | 105 int Builtins::construct_call_pc_offset_ = 0; |
| 129 int Builtins::arguments_adaptor_call_pc_offset_ = 0; | 106 int Builtins::arguments_adaptor_call_pc_offset_ = 0; |
| 130 | 107 |
| 131 | 108 |
| 132 // Check if the builtin was called in a 'new' call. | 109 // Check if the builtin was called in a 'new' call. |
| 133 bool Builtins::IsConstructCall(Address pc) { | 110 bool Builtins::IsConstructCall(Address pc) { |
| 134 ASSERT(construct_call_pc_offset_ > 0); | 111 ASSERT(construct_call_pc_offset_ > 0); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 BUILTIN_END | 149 BUILTIN_END |
| 173 | 150 |
| 174 | 151 |
| 175 BUILTIN(EmptyFunction) { | 152 BUILTIN(EmptyFunction) { |
| 176 } | 153 } |
| 177 BUILTIN_END | 154 BUILTIN_END |
| 178 | 155 |
| 179 | 156 |
| 180 BUILTIN(ArrayCode) { | 157 BUILTIN(ArrayCode) { |
| 181 JSArray* array; | 158 JSArray* array; |
| 182 if (is_construct) { | 159 if (CalledAsConstructor()) { |
| 183 array = JSArray::cast(*receiver); | 160 array = JSArray::cast(*receiver); |
| 184 } else { | 161 } else { |
| 185 // Allocate the JS Array | 162 // Allocate the JS Array |
| 186 JSFunction* constructor = | 163 JSFunction* constructor = |
| 187 Top::context()->global_context()->array_function(); | 164 Top::context()->global_context()->array_function(); |
| 188 Object* obj = Heap::AllocateJSObject(constructor); | 165 Object* obj = Heap::AllocateJSObject(constructor); |
| 189 if (obj->IsFailure()) return obj; | 166 if (obj->IsFailure()) return obj; |
| 190 array = JSArray::cast(obj); | 167 array = JSArray::cast(obj); |
| 191 } | 168 } |
| 192 | 169 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 | 205 |
| 229 // Set length and elements on the array. | 206 // Set length and elements on the array. |
| 230 array->set_elements(FixedArray::cast(obj)); | 207 array->set_elements(FixedArray::cast(obj)); |
| 231 array->set_length(len); | 208 array->set_length(len); |
| 232 | 209 |
| 233 return array; | 210 return array; |
| 234 } | 211 } |
| 235 BUILTIN_END | 212 BUILTIN_END |
| 236 | 213 |
| 237 | 214 |
| 238 NEW_BUILTIN(ArrayPush) { | 215 BUILTIN(ArrayPush) { |
| 239 JSArray* array = JSArray::cast(*receiver); | 216 JSArray* array = JSArray::cast(*receiver); |
| 240 ASSERT(array->HasFastElements()); | 217 ASSERT(array->HasFastElements()); |
| 241 | 218 |
| 242 // Make sure we have space for the elements. | 219 // Make sure we have space for the elements. |
| 243 int len = Smi::cast(array->length())->value(); | 220 int len = Smi::cast(array->length())->value(); |
| 244 | 221 |
| 245 // Set new length. | 222 // Set new length. |
| 246 int new_length = len + __argc__ - 1; | 223 int new_length = len + __argc__ - 1; |
| 247 FixedArray* elms = FixedArray::cast(array->elements()); | 224 FixedArray* elms = FixedArray::cast(array->elements()); |
| 248 | 225 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 267 // Set the new backing storage. | 244 // Set the new backing storage. |
| 268 array->set_elements(new_elms); | 245 array->set_elements(new_elms); |
| 269 } | 246 } |
| 270 // Set the length. | 247 // Set the length. |
| 271 array->set_length(Smi::FromInt(new_length)); | 248 array->set_length(Smi::FromInt(new_length)); |
| 272 return array->length(); | 249 return array->length(); |
| 273 } | 250 } |
| 274 BUILTIN_END | 251 BUILTIN_END |
| 275 | 252 |
| 276 | 253 |
| 277 NEW_BUILTIN(ArrayPop) { | 254 BUILTIN(ArrayPop) { |
| 278 JSArray* array = JSArray::cast(*receiver); | 255 JSArray* array = JSArray::cast(*receiver); |
| 279 ASSERT(array->HasFastElements()); | 256 ASSERT(array->HasFastElements()); |
| 280 Object* undefined = Heap::undefined_value(); | 257 Object* undefined = Heap::undefined_value(); |
| 281 | 258 |
| 282 int len = Smi::cast(array->length())->value(); | 259 int len = Smi::cast(array->length())->value(); |
| 283 if (len == 0) return undefined; | 260 if (len == 0) return undefined; |
| 284 | 261 |
| 285 // Get top element | 262 // Get top element |
| 286 FixedArray* elms = FixedArray::cast(array->elements()); | 263 FixedArray* elms = FixedArray::cast(array->elements()); |
| 287 Object* top = elms->get(len - 1); | 264 Object* top = elms->get(len - 1); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 } | 331 } |
| 355 } | 332 } |
| 356 if (current == Heap::null_value()) *arg = Heap::undefined_value(); | 333 if (current == Heap::null_value()) *arg = Heap::undefined_value(); |
| 357 } | 334 } |
| 358 return holder; | 335 return holder; |
| 359 } | 336 } |
| 360 | 337 |
| 361 | 338 |
| 362 BUILTIN(HandleApiCall) { | 339 BUILTIN(HandleApiCall) { |
| 363 HandleScope scope; | 340 HandleScope scope; |
| 341 bool is_construct = CalledAsConstructor(); |
| 364 | 342 |
| 365 // TODO(1238487): This is not nice. We need to get rid of this | 343 // TODO(1238487): This is not nice. We need to get rid of this |
| 366 // kludgy behavior and start handling API calls in a more direct | 344 // kludgy behavior and start handling API calls in a more direct |
| 367 // way - maybe compile specialized stubs lazily?. | 345 // way - maybe compile specialized stubs lazily?. |
| 368 Handle<JSFunction> function = | 346 Handle<JSFunction> function = |
| 369 Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function)); | 347 Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function)); |
| 370 | 348 |
| 371 if (is_construct) { | 349 if (is_construct) { |
| 372 Handle<FunctionTemplateInfo> desc = | 350 Handle<FunctionTemplateInfo> desc = |
| 373 Handle<FunctionTemplateInfo>( | 351 Handle<FunctionTemplateInfo>( |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 | 412 |
| 435 return *receiver; | 413 return *receiver; |
| 436 } | 414 } |
| 437 BUILTIN_END | 415 BUILTIN_END |
| 438 | 416 |
| 439 | 417 |
| 440 // Handle calls to non-function objects created through the API that | 418 // Handle calls to non-function objects created through the API that |
| 441 // support calls. | 419 // support calls. |
| 442 BUILTIN(HandleApiCallAsFunction) { | 420 BUILTIN(HandleApiCallAsFunction) { |
| 443 // Non-functions are never called as constructors. | 421 // Non-functions are never called as constructors. |
| 444 ASSERT(!is_construct); | 422 ASSERT(!CalledAsConstructor()); |
| 445 | 423 |
| 446 // Get the object called. | 424 // Get the object called. |
| 447 JSObject* obj = JSObject::cast(*receiver); | 425 JSObject* obj = JSObject::cast(*receiver); |
| 448 | 426 |
| 449 // Get the invocation callback from the function descriptor that was | 427 // Get the invocation callback from the function descriptor that was |
| 450 // used to create the called object. | 428 // used to create the called object. |
| 451 ASSERT(obj->map()->has_instance_call_handler()); | 429 ASSERT(obj->map()->has_instance_call_handler()); |
| 452 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); | 430 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); |
| 453 Object* template_info = constructor->shared()->function_data(); | 431 Object* template_info = constructor->shared()->function_data(); |
| 454 Object* handler = | 432 Object* handler = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 467 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); | 445 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); |
| 468 Handle<Object> data_handle(data_obj); | 446 Handle<Object> data_handle(data_obj); |
| 469 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); | 447 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); |
| 470 Handle<JSFunction> callee_handle(constructor); | 448 Handle<JSFunction> callee_handle(constructor); |
| 471 v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle); | 449 v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle); |
| 472 LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver))); | 450 LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver))); |
| 473 v8::Arguments args = v8::ImplementationUtilities::NewArguments( | 451 v8::Arguments args = v8::ImplementationUtilities::NewArguments( |
| 474 data, | 452 data, |
| 475 self, | 453 self, |
| 476 callee, | 454 callee, |
| 477 is_construct, | 455 false, |
| 478 reinterpret_cast<void**>(__argv__ - 1), | 456 reinterpret_cast<void**>(__argv__ - 1), |
| 479 __argc__ - 1); | 457 __argc__ - 1); |
| 480 v8::Handle<v8::Value> value; | 458 v8::Handle<v8::Value> value; |
| 481 { | 459 { |
| 482 // Leaving JavaScript. | 460 // Leaving JavaScript. |
| 483 VMState state(OTHER); | 461 VMState state(OTHER); |
| 484 value = callback(args); | 462 value = callback(args); |
| 485 } | 463 } |
| 486 if (value.IsEmpty()) { | 464 if (value.IsEmpty()) { |
| 487 result = Heap::undefined_value(); | 465 result = Heap::undefined_value(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 | 577 |
| 600 | 578 |
| 601 static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { | 579 static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { |
| 602 KeyedStoreIC::GenerateInitialize(masm); | 580 KeyedStoreIC::GenerateInitialize(masm); |
| 603 } | 581 } |
| 604 | 582 |
| 605 | 583 |
| 606 Object* Builtins::builtins_[builtin_count] = { NULL, }; | 584 Object* Builtins::builtins_[builtin_count] = { NULL, }; |
| 607 const char* Builtins::names_[builtin_count] = { NULL, }; | 585 const char* Builtins::names_[builtin_count] = { NULL, }; |
| 608 | 586 |
| 609 #define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name), | 587 #define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name), |
| 610 Address Builtins::c_functions_[cfunction_count] = { | 588 Address Builtins::c_functions_[cfunction_count] = { |
| 611 BUILTIN_LIST_C(DEF_ENUM_C) | 589 BUILTIN_LIST_C(DEF_ENUM_C) |
| 612 }; | 590 }; |
| 613 #undef DEF_ENUM_C | 591 #undef DEF_ENUM_C |
| 614 | 592 |
| 615 #define DEF_JS_NAME(name, ignore) #name, | 593 #define DEF_JS_NAME(name, ignore) #name, |
| 616 #define DEF_JS_ARGC(ignore, argc) argc, | 594 #define DEF_JS_ARGC(ignore, argc) argc, |
| 617 const char* Builtins::javascript_names_[id_count] = { | 595 const char* Builtins::javascript_names_[id_count] = { |
| 618 BUILTINS_LIST_JS(DEF_JS_NAME) | 596 BUILTINS_LIST_JS(DEF_JS_NAME) |
| 619 }; | 597 }; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 630 | 608 |
| 631 // Create a scope for the handles in the builtins. | 609 // Create a scope for the handles in the builtins. |
| 632 HandleScope scope; | 610 HandleScope scope; |
| 633 | 611 |
| 634 struct BuiltinDesc { | 612 struct BuiltinDesc { |
| 635 byte* generator; | 613 byte* generator; |
| 636 byte* c_code; | 614 byte* c_code; |
| 637 const char* s_name; // name is only used for generating log information. | 615 const char* s_name; // name is only used for generating log information. |
| 638 int name; | 616 int name; |
| 639 Code::Flags flags; | 617 Code::Flags flags; |
| 640 int argc; | |
| 641 }; | 618 }; |
| 642 | 619 |
| 643 #define DEF_FUNCTION_PTR_C(name, argc) \ | 620 #define DEF_FUNCTION_PTR_C(name) \ |
| 644 { FUNCTION_ADDR(Generate_Adaptor), \ | 621 { FUNCTION_ADDR(Generate_Adaptor), \ |
| 645 FUNCTION_ADDR(Builtin_##name), \ | 622 FUNCTION_ADDR(Builtin_##name), \ |
| 646 #name, \ | 623 #name, \ |
| 647 c_##name, \ | 624 c_##name, \ |
| 648 Code::ComputeFlags(Code::BUILTIN), \ | 625 Code::ComputeFlags(Code::BUILTIN) \ |
| 649 argc \ | |
| 650 }, | 626 }, |
| 651 | 627 |
| 652 #define DEF_FUNCTION_PTR_A(name, kind, state) \ | 628 #define DEF_FUNCTION_PTR_A(name, kind, state) \ |
| 653 { FUNCTION_ADDR(Generate_##name), \ | 629 { FUNCTION_ADDR(Generate_##name), \ |
| 654 NULL, \ | 630 NULL, \ |
| 655 #name, \ | 631 #name, \ |
| 656 name, \ | 632 name, \ |
| 657 Code::ComputeFlags(Code::kind, state), \ | 633 Code::ComputeFlags(Code::kind, state) \ |
| 658 -1 \ | |
| 659 }, | 634 }, |
| 660 | 635 |
| 661 // Define array of pointers to generators and C builtin functions. | 636 // Define array of pointers to generators and C builtin functions. |
| 662 static BuiltinDesc functions[] = { | 637 static BuiltinDesc functions[] = { |
| 663 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) | 638 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) |
| 664 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) | 639 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) |
| 665 // Terminator: | 640 // Terminator: |
| 666 { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0), -1} | 641 { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0) } |
| 667 }; | 642 }; |
| 668 | 643 |
| 669 #undef DEF_FUNCTION_PTR_C | 644 #undef DEF_FUNCTION_PTR_C |
| 670 #undef DEF_FUNCTION_PTR_A | 645 #undef DEF_FUNCTION_PTR_A |
| 671 | 646 |
| 672 // For now we generate builtin adaptor code into a stack-allocated | 647 // For now we generate builtin adaptor code into a stack-allocated |
| 673 // buffer, before copying it into individual code objects. | 648 // buffer, before copying it into individual code objects. |
| 674 byte buffer[4*KB]; | 649 byte buffer[4*KB]; |
| 675 | 650 |
| 676 // Traverse the list of builtins and generate an adaptor in a | 651 // Traverse the list of builtins and generate an adaptor in a |
| 677 // separate code object for each one. | 652 // separate code object for each one. |
| 678 for (int i = 0; i < builtin_count; i++) { | 653 for (int i = 0; i < builtin_count; i++) { |
| 679 if (create_heap_objects) { | 654 if (create_heap_objects) { |
| 680 MacroAssembler masm(buffer, sizeof buffer); | 655 MacroAssembler masm(buffer, sizeof buffer); |
| 681 // Generate the code/adaptor. | 656 // Generate the code/adaptor. |
| 682 typedef void (*Generator)(MacroAssembler*, int, int); | 657 typedef void (*Generator)(MacroAssembler*, int); |
| 683 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); | 658 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
| 684 // We pass all arguments to the generator, but it may not use all of | 659 // We pass all arguments to the generator, but it may not use all of |
| 685 // them. This works because the first arguments are on top of the | 660 // them. This works because the first arguments are on top of the |
| 686 // stack. | 661 // stack. |
| 687 g(&masm, functions[i].argc, functions[i].name); | 662 g(&masm, functions[i].name); |
| 688 // Move the code into the object heap. | 663 // Move the code into the object heap. |
| 689 CodeDesc desc; | 664 CodeDesc desc; |
| 690 masm.GetCode(&desc); | 665 masm.GetCode(&desc); |
| 691 Code::Flags flags = functions[i].flags; | 666 Code::Flags flags = functions[i].flags; |
| 692 Object* code = Heap::CreateCode(desc, NULL, flags); | 667 Object* code = Heap::CreateCode(desc, NULL, flags); |
| 693 if (code->IsRetryAfterGC()) { | 668 if (code->IsRetryAfterGC()) { |
| 694 CHECK(Heap::CollectGarbage(Failure::cast(code)->requested(), | 669 CHECK(Heap::CollectGarbage(Failure::cast(code)->requested(), |
| 695 Failure::cast(code)->allocation_space())); | 670 Failure::cast(code)->allocation_space())); |
| 696 code = Heap::CreateCode(desc, NULL, flags); | 671 code = Heap::CreateCode(desc, NULL, flags); |
| 697 } | 672 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 if (entry->contains(pc)) { | 712 if (entry->contains(pc)) { |
| 738 return names_[i]; | 713 return names_[i]; |
| 739 } | 714 } |
| 740 } | 715 } |
| 741 } | 716 } |
| 742 return NULL; | 717 return NULL; |
| 743 } | 718 } |
| 744 | 719 |
| 745 | 720 |
| 746 } } // namespace v8::internal | 721 } } // namespace v8::internal |
| OLD | NEW |