Chromium Code Reviews| 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 |