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 |