OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2905 // - target function | 2905 // - target function |
2906 // - this (receiver) | 2906 // - this (receiver) |
2907 EmitCall(expr, CallICState::METHOD); | 2907 EmitCall(expr, CallICState::METHOD); |
2908 } | 2908 } |
2909 | 2909 |
2910 | 2910 |
2911 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2911 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
2912 // Load the arguments. | 2912 // Load the arguments. |
2913 ZoneList<Expression*>* args = expr->arguments(); | 2913 ZoneList<Expression*>* args = expr->arguments(); |
2914 int arg_count = args->length(); | 2914 int arg_count = args->length(); |
2915 if (expr->HasSpreadArguments()) { | |
2916 __ movp(rax, Immediate(arg_count)); | |
2917 } | |
2918 | |
2915 { PreservePositionScope scope(masm()->positions_recorder()); | 2919 { PreservePositionScope scope(masm()->positions_recorder()); |
2916 for (int i = 0; i < arg_count; i++) { | 2920 for (int i = 0; i < arg_count; i++) { |
2917 VisitForStackValue(args->at(i)); | 2921 Expression* e = args->at(i); |
2922 if (e->IsSpreadOperation()) { | |
2923 DoSpreadArgument(e->AsSpreadOperation(), rax); | |
2924 } else { | |
2925 VisitForStackValue(args->at(i)); | |
2926 } | |
2918 } | 2927 } |
2919 } | 2928 } |
2920 | 2929 |
2921 // Record source position of the IC call. | 2930 // Record source position of the IC call. |
2922 SetSourcePosition(expr->position()); | 2931 SetSourcePosition(expr->position()); |
2923 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2932 if (expr->HasSpreadArguments()) { |
2924 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | 2933 CallFunctionFlags flags = call_type == CallICState::METHOD ? |
2925 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2934 CALL_AS_METHOD : NO_CALL_FUNCTION_FLAGS; |
2926 // Don't assign a type feedback id to the IC, since type feedback is provided | 2935 CallFunctionStub stub(isolate(), arg_count, flags, true); |
2927 // by the vector above. | 2936 __ movp(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
2928 CallIC(ic); | 2937 __ CallStub(&stub); |
2938 } else { | |
2939 Handle<Code> ic = | |
2940 CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | |
2941 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | |
2942 | |
2943 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | |
2944 | |
2945 // Don't assign a type feedback id to the IC, since type feedback is | |
2946 // provided by the vector above. | |
2947 CallIC(ic); | |
2948 } | |
2929 | 2949 |
2930 RecordJSReturnSite(expr); | 2950 RecordJSReturnSite(expr); |
2931 | 2951 |
2932 // Restore context register. | 2952 // Restore context register. |
2933 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2953 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2934 // Discard the function left on TOS. | 2954 // Discard the function left on TOS. |
2935 context()->DropAndPlug(1, rax); | 2955 context()->DropAndPlug(1, rax); |
2936 } | 2956 } |
2937 | 2957 |
2938 | 2958 |
(...skipping 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5102 } else { | 5122 } else { |
5103 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 5123 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
5104 CallIC(ic, expr->CompareOperationFeedbackId()); | 5124 CallIC(ic, expr->CompareOperationFeedbackId()); |
5105 __ testp(rax, rax); | 5125 __ testp(rax, rax); |
5106 Split(not_zero, if_true, if_false, fall_through); | 5126 Split(not_zero, if_true, if_false, fall_through); |
5107 } | 5127 } |
5108 context()->Plug(if_true, if_false); | 5128 context()->Plug(if_true, if_false); |
5109 } | 5129 } |
5110 | 5130 |
5111 | 5131 |
5132 void FullCodeGenerator::DoSpreadArgument(SpreadOperation* expr, | |
5133 Register arg_count) { | |
5134 Comment cmnt(masm_, "[ SpreadArgument"); | |
5135 | |
5136 Label loop, not_done, done; | |
5137 | |
5138 __ decp(arg_count); | |
5139 __ pushq(arg_count); | |
5140 | |
5141 // var iterator = iterable[Symbol.iterator](); | |
5142 VisitForEffect(expr->assign_iterator()); | |
5143 | |
5144 // Loop entry. | |
5145 __ bind(&loop); | |
5146 | |
5147 // result = iterator.next() | |
5148 VisitForEffect(expr->next_result()); | |
5149 | |
5150 // if (result.done) break; | |
5151 VisitForControl(expr->result_done(), &done, ¬_done, ¬_done); | |
5152 __ bind(¬_done); | |
5153 | |
5154 // %rax = result.value | |
5155 VisitForAccumulatorValue(expr->result_value()); | |
arv (Not doing code reviews)
2015/02/12 21:41:34
Why not VisitForStackValue?
caitp (gmail)
2015/02/12 21:58:54
right now, it's sort of like this:
before first v
| |
5156 __ pushq(Operand(rsp, 0)); | |
5157 __ incp(Operand(rsp, 0)); | |
5158 __ movp(Operand(rsp, 1 * kPointerSize), rax); | |
5159 | |
5160 // loop | |
5161 __ jmp(&loop); | |
5162 | |
5163 __ bind(&done); | |
5164 __ popq(arg_count); | |
5165 } | |
5166 | |
5167 | |
5168 void FullCodeGenerator::VisitSpreadOperation(SpreadOperation* expr) { | |
5169 UNREACHABLE(); | |
5170 } | |
5171 | |
5172 | |
5112 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 5173 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
5113 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 5174 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
5114 context()->Plug(rax); | 5175 context()->Plug(rax); |
5115 } | 5176 } |
5116 | 5177 |
5117 | 5178 |
5118 Register FullCodeGenerator::result_register() { | 5179 Register FullCodeGenerator::result_register() { |
5119 return rax; | 5180 return rax; |
5120 } | 5181 } |
5121 | 5182 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5329 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5390 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5330 Assembler::target_address_at(call_target_address, | 5391 Assembler::target_address_at(call_target_address, |
5331 unoptimized_code)); | 5392 unoptimized_code)); |
5332 return OSR_AFTER_STACK_CHECK; | 5393 return OSR_AFTER_STACK_CHECK; |
5333 } | 5394 } |
5334 | 5395 |
5335 | 5396 |
5336 } } // namespace v8::internal | 5397 } } // namespace v8::internal |
5337 | 5398 |
5338 #endif // V8_TARGET_ARCH_X64 | 5399 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |