 Chromium Code Reviews
 Chromium Code Reviews Issue 136403005:
  Remove CALL_AS_FUNCTION and CALL_AS_METHOD.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 136403005:
  Remove CALL_AS_FUNCTION and CALL_AS_METHOD.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2516 // edi : the function to call | 2516 // edi : the function to call | 
| 2517 Isolate* isolate = masm->isolate(); | 2517 Isolate* isolate = masm->isolate(); | 
| 2518 Label slow, non_function; | 2518 Label slow, non_function; | 
| 2519 | 2519 | 
| 2520 // Check that the function really is a JavaScript function. | 2520 // Check that the function really is a JavaScript function. | 
| 2521 __ JumpIfSmi(edi, &non_function); | 2521 __ JumpIfSmi(edi, &non_function); | 
| 2522 | 2522 | 
| 2523 // The receiver might implicitly be the global object. This is | 2523 // The receiver might implicitly be the global object. This is | 
| 2524 // indicated by passing the hole as the receiver to the call | 2524 // indicated by passing the hole as the receiver to the call | 
| 2525 // function stub. | 2525 // function stub. | 
| 2526 Label call; | |
| 2527 if (ReceiverMightBeImplicit()) { | 2526 if (ReceiverMightBeImplicit()) { | 
| 2528 Label try_call, patch_current_context; | 2527 Label try_call, patch_current_context; | 
| 2529 if (ReceiverMightBeImplicit()) { | 2528 // Get the receiver from the stack. | 
| 2530 // Get the receiver from the stack. | 2529 // +1 ~ return address | 
| 2531 // +1 ~ return address | 2530 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); | 
| 2532 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); | 2531 // Call as function is indicated with the hole. | 
| 2533 // Call as function is indicated with the hole. | 2532 __ cmp(eax, isolate->factory()->the_hole_value()); | 
| 2534 __ cmp(eax, isolate->factory()->the_hole_value()); | 2533 __ j(not_equal, &try_call, Label::kNear); | 
| 2535 __ j(not_equal, &try_call, Label::kNear); | |
| 2536 } | |
| 2537 | 2534 | 
| 2538 // Patch the global object on the stack. | 2535 // Patch the global object on the stack. | 
| 2539 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), | 2536 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), | 
| 2540 isolate->factory()->undefined_value()); | 2537 isolate->factory()->undefined_value()); | 
| 2541 | 2538 | 
| 2542 // Goto slow case if we do not have a function. | |
| 2543 __ bind(&try_call); | 2539 __ bind(&try_call); | 
| 2544 } | 2540 } | 
| 2545 | 2541 | 
| 2546 // Goto slow case if we do not have a function. | 2542 // Goto slow case if we do not have a function. | 
| 2547 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2543 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 
| 2548 __ j(not_equal, &slow); | 2544 __ j(not_equal, &slow); | 
| 2549 | 2545 | 
| 2550 __ bind(&call); | |
| 2551 | |
| 2552 if (RecordCallTarget()) { | 2546 if (RecordCallTarget()) { | 
| 2553 GenerateRecordCallTarget(masm); | 2547 GenerateRecordCallTarget(masm); | 
| 2554 } | 2548 } | 
| 2555 | 2549 | 
| 2556 // Fast-case: Just invoke the function. | 2550 // Fast-case: Just invoke the function. | 
| 2557 ParameterCount actual(argc_); | 2551 ParameterCount actual(argc_); | 
| 2558 | 2552 | 
| 2559 if (ReceiverMightBeImplicit()) { | 2553 if (ReceiverMightBeImplicit()) { | 
| 
dcarney
2014/01/13 18:39:35
this block can be removed
 | |
| 2560 Label call_as_function; | 2554 Label call_as_function; | 
| 2561 __ cmp(eax, isolate->factory()->the_hole_value()); | 2555 __ cmp(eax, isolate->factory()->the_hole_value()); | 
| 2562 __ j(equal, &call_as_function); | 2556 __ j(equal, &call_as_function); | 
| 2563 __ InvokeFunction(edi, | 2557 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 
| 2564 actual, | |
| 2565 JUMP_FUNCTION, | |
| 2566 NullCallWrapper(), | |
| 2567 CALL_AS_METHOD); | |
| 2568 __ bind(&call_as_function); | 2558 __ bind(&call_as_function); | 
| 2569 } | 2559 } | 
| 2570 __ InvokeFunction(edi, | 2560 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 
| 2571 actual, | |
| 2572 JUMP_FUNCTION, | |
| 2573 NullCallWrapper(), | |
| 2574 CALL_AS_FUNCTION); | |
| 2575 | 2561 | 
| 2576 // Slow-case: Non-function called. | 2562 // Slow-case: Non-function called. | 
| 2577 __ bind(&slow); | 2563 __ bind(&slow); | 
| 2578 if (RecordCallTarget()) { | 2564 if (RecordCallTarget()) { | 
| 2579 // If there is a call target cache, mark it megamorphic in the | 2565 // If there is a call target cache, mark it megamorphic in the | 
| 2580 // non-function case. MegamorphicSentinel is an immortal immovable | 2566 // non-function case. MegamorphicSentinel is an immortal immovable | 
| 2581 // object (undefined) so no write barrier is needed. | 2567 // object (undefined) so no write barrier is needed. | 
| 2582 __ mov(FieldOperand(ebx, Cell::kValueOffset), | 2568 __ mov(FieldOperand(ebx, Cell::kValueOffset), | 
| 2583 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 2569 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 
| 2584 } | 2570 } | 
| 2585 // Check for function proxy. | 2571 // Check for function proxy. | 
| 2586 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | 2572 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | 
| 2587 __ j(not_equal, &non_function); | 2573 __ j(not_equal, &non_function); | 
| 2588 __ pop(ecx); | 2574 __ pop(ecx); | 
| 2589 __ push(edi); // put proxy as additional argument under return address | 2575 __ push(edi); // put proxy as additional argument under return address | 
| 2590 __ push(ecx); | 2576 __ push(ecx); | 
| 2591 __ Set(eax, Immediate(argc_ + 1)); | 2577 __ Set(eax, Immediate(argc_ + 1)); | 
| 2592 __ Set(ebx, Immediate(0)); | 2578 __ Set(ebx, Immediate(0)); | 
| 2593 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 2594 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 2579 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 
| 2595 { | 2580 { | 
| 2596 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 2581 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 
| 2597 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 2582 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 
| 2598 } | 2583 } | 
| 2599 | 2584 | 
| 2600 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 2585 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 
| 2601 // of the original receiver from the call site). | 2586 // of the original receiver from the call site). | 
| 2602 __ bind(&non_function); | 2587 __ bind(&non_function); | 
| 2603 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); | 2588 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); | 
| 2604 __ Set(eax, Immediate(argc_)); | 2589 __ Set(eax, Immediate(argc_)); | 
| 2605 __ Set(ebx, Immediate(0)); | 2590 __ Set(ebx, Immediate(0)); | 
| 2606 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 2607 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 2591 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 
| 2608 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 2592 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 
| 2609 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 2593 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 
| 2610 } | 2594 } | 
| 2611 | 2595 | 
| 2612 | 2596 | 
| 2613 void CallConstructStub::Generate(MacroAssembler* masm) { | 2597 void CallConstructStub::Generate(MacroAssembler* masm) { | 
| 2614 // eax : number of arguments | 2598 // eax : number of arguments | 
| 2615 // ebx : cache cell for call target | 2599 // ebx : cache cell for call target | 
| 2616 // edi : constructor function | 2600 // edi : constructor function | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2644 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 2628 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 
| 2645 __ jmp(&do_call); | 2629 __ jmp(&do_call); | 
| 2646 | 2630 | 
| 2647 __ bind(&non_function_call); | 2631 __ bind(&non_function_call); | 
| 2648 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 2632 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 
| 2649 __ bind(&do_call); | 2633 __ bind(&do_call); | 
| 2650 // Set expected number of arguments to zero (not changing eax). | 2634 // Set expected number of arguments to zero (not changing eax). | 
| 2651 __ Set(ebx, Immediate(0)); | 2635 __ Set(ebx, Immediate(0)); | 
| 2652 Handle<Code> arguments_adaptor = | 2636 Handle<Code> arguments_adaptor = | 
| 2653 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 2637 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 
| 2654 __ SetCallKind(ecx, CALL_AS_METHOD); | |
| 2655 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); | 2638 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); | 
| 2656 } | 2639 } | 
| 2657 | 2640 | 
| 2658 | 2641 | 
| 2659 bool CEntryStub::NeedsImmovableCode() { | 2642 bool CEntryStub::NeedsImmovableCode() { | 
| 2660 return false; | 2643 return false; | 
| 2661 } | 2644 } | 
| 2662 | 2645 | 
| 2663 | 2646 | 
| 2664 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 2647 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 
| (...skipping 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5343 __ mov(edi, eax); | 5326 __ mov(edi, eax); | 
| 5344 int parameter_count_offset = | 5327 int parameter_count_offset = | 
| 5345 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | 5328 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | 
| 5346 __ mov(eax, MemOperand(ebp, parameter_count_offset)); | 5329 __ mov(eax, MemOperand(ebp, parameter_count_offset)); | 
| 5347 // The parameter count above includes the receiver for the arguments passed to | 5330 // The parameter count above includes the receiver for the arguments passed to | 
| 5348 // the deoptimization handler. Subtract the receiver for the parameter count | 5331 // the deoptimization handler. Subtract the receiver for the parameter count | 
| 5349 // for the call. | 5332 // for the call. | 
| 5350 __ sub(eax, Immediate(1)); | 5333 __ sub(eax, Immediate(1)); | 
| 5351 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 5334 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 
| 5352 ParameterCount argument_count(eax); | 5335 ParameterCount argument_count(eax); | 
| 5353 __ InvokeFunction( | 5336 __ InvokeFunction(edi, argument_count, JUMP_FUNCTION, NullCallWrapper()); | 
| 5354 edi, argument_count, JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
| 5355 } | 5337 } | 
| 5356 | 5338 | 
| 5357 | 5339 | 
| 5358 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 5340 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 
| 5359 if (masm->isolate()->function_entry_hook() != NULL) { | 5341 if (masm->isolate()->function_entry_hook() != NULL) { | 
| 5360 ProfileEntryHookStub stub; | 5342 ProfileEntryHookStub stub; | 
| 5361 masm->CallStub(&stub); | 5343 masm->CallStub(&stub); | 
| 5362 } | 5344 } | 
| 5363 } | 5345 } | 
| 5364 | 5346 | 
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5713 __ bind(&fast_elements_case); | 5695 __ bind(&fast_elements_case); | 
| 5714 GenerateCase(masm, FAST_ELEMENTS); | 5696 GenerateCase(masm, FAST_ELEMENTS); | 
| 5715 } | 5697 } | 
| 5716 | 5698 | 
| 5717 | 5699 | 
| 5718 #undef __ | 5700 #undef __ | 
| 5719 | 5701 | 
| 5720 } } // namespace v8::internal | 5702 } } // namespace v8::internal | 
| 5721 | 5703 | 
| 5722 #endif // V8_TARGET_ARCH_IA32 | 5704 #endif // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |