Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 132623005: A64: Synchronize with r18642. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
131 __ int3(); 131 __ int3();
132 } 132 }
133 #endif 133 #endif
134 134
135 // Classic mode functions and builtins need to replace the receiver with the 135 // Classic mode functions and builtins need to replace the receiver with the
136 // global proxy when called as functions (without an explicit receiver 136 // global proxy when called as functions (without an explicit receiver
137 // object). 137 // object).
138 if (info->is_classic_mode() && !info->is_native()) { 138 if (info->is_classic_mode() && !info->is_native()) {
139 Label ok; 139 Label ok;
140 __ testq(rcx, rcx);
141 __ j(zero, &ok, Label::kNear);
142
143 // +1 for return address. 140 // +1 for return address.
144 StackArgumentsAccessor args(rsp, info->scope()->num_parameters()); 141 StackArgumentsAccessor args(rsp, info->scope()->num_parameters());
145 __ movq(rcx, args.GetReceiverOperand()); 142 __ movq(rcx, args.GetReceiverOperand());
146 143
147 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); 144 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
148 __ j(not_equal, &ok, Label::kNear); 145 __ j(not_equal, &ok, Label::kNear);
149 146
150 __ movq(rcx, GlobalObjectOperand()); 147 __ movq(rcx, GlobalObjectOperand());
151 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 148 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
152 149
(...skipping 1941 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 break; 2091 break;
2095 } 2092 }
2096 } 2093 }
2097 } 2094 }
2098 2095
2099 2096
2100 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2097 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2101 Expression *value, 2098 Expression *value,
2102 JSGeneratorObject::ResumeMode resume_mode) { 2099 JSGeneratorObject::ResumeMode resume_mode) {
2103 // The value stays in rax, and is ultimately read by the resumed generator, as 2100 // The value stays in rax, and is ultimately read by the resumed generator, as
2104 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. rbx 2101 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
2105 // will hold the generator object until the activation has been resumed. 2102 // is read to throw the value when the resumed generator is already closed.
2103 // rbx will hold the generator object until the activation has been resumed.
2106 VisitForStackValue(generator); 2104 VisitForStackValue(generator);
2107 VisitForAccumulatorValue(value); 2105 VisitForAccumulatorValue(value);
2108 __ pop(rbx); 2106 __ pop(rbx);
2109 2107
2110 // Check generator state. 2108 // Check generator state.
2111 Label wrong_state, done; 2109 Label wrong_state, closed_state, done;
2112 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0); 2110 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
2113 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0); 2111 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
2114 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), 2112 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
2115 Smi::FromInt(0)); 2113 Smi::FromInt(0));
2116 __ j(less_equal, &wrong_state); 2114 __ j(equal, &closed_state);
2115 __ j(less, &wrong_state);
2117 2116
2118 // Load suspended function and context. 2117 // Load suspended function and context.
2119 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); 2118 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
2120 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); 2119 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
2121 2120
2122 // Push receiver. 2121 // Push receiver.
2123 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); 2122 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset));
2124 2123
2125 // Push holes for arguments to generator function. 2124 // Push holes for arguments to generator function.
2126 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2125 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 __ push(rcx); 2176 __ push(rcx);
2178 __ jmp(&push_operand_holes); 2177 __ jmp(&push_operand_holes);
2179 __ bind(&call_resume); 2178 __ bind(&call_resume);
2180 __ push(rbx); 2179 __ push(rbx);
2181 __ push(result_register()); 2180 __ push(result_register());
2182 __ Push(Smi::FromInt(resume_mode)); 2181 __ Push(Smi::FromInt(resume_mode));
2183 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2182 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2184 // Not reached: the runtime call returns elsewhere. 2183 // Not reached: the runtime call returns elsewhere.
2185 __ Abort(kGeneratorFailedToResume); 2184 __ Abort(kGeneratorFailedToResume);
2186 2185
2186 // Reach here when generator is closed.
2187 __ bind(&closed_state);
2188 if (resume_mode == JSGeneratorObject::NEXT) {
2189 // Return completed iterator result when generator is closed.
2190 __ PushRoot(Heap::kUndefinedValueRootIndex);
2191 // Pop value from top-of-stack slot; box result into result register.
2192 EmitCreateIteratorResult(true);
2193 } else {
2194 // Throw the provided value.
2195 __ push(rax);
2196 __ CallRuntime(Runtime::kThrow, 1);
2197 }
2198 __ jmp(&done);
2199
2187 // Throw error if we attempt to operate on a running generator. 2200 // Throw error if we attempt to operate on a running generator.
2188 __ bind(&wrong_state); 2201 __ bind(&wrong_state);
2189 __ push(rbx); 2202 __ push(rbx);
2190 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2203 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2191 2204
2192 __ bind(&done); 2205 __ bind(&done);
2193 context()->Plug(result_register()); 2206 context()->Plug(result_register());
2194 } 2207 }
2195 2208
2196 2209
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 int arg_count = args->length(); 2544 int arg_count = args->length();
2532 { PreservePositionScope scope(masm()->positions_recorder()); 2545 { PreservePositionScope scope(masm()->positions_recorder());
2533 for (int i = 0; i < arg_count; i++) { 2546 for (int i = 0; i < arg_count; i++) {
2534 VisitForStackValue(args->at(i)); 2547 VisitForStackValue(args->at(i));
2535 } 2548 }
2536 __ Move(rcx, name); 2549 __ Move(rcx, name);
2537 } 2550 }
2538 // Record source position for debugger. 2551 // Record source position for debugger.
2539 SetSourcePosition(expr->position()); 2552 SetSourcePosition(expr->position());
2540 // Call the IC initialization code. 2553 // Call the IC initialization code.
2541 Handle<Code> ic = 2554 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count);
2542 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2543 TypeFeedbackId ast_id = mode == CONTEXTUAL 2555 TypeFeedbackId ast_id = mode == CONTEXTUAL
2544 ? TypeFeedbackId::None() 2556 ? TypeFeedbackId::None()
2545 : expr->CallFeedbackId(); 2557 : expr->CallFeedbackId();
2546 CallIC(ic, mode, ast_id); 2558 CallIC(ic, mode, ast_id);
2547 RecordJSReturnSite(expr); 2559 RecordJSReturnSite(expr);
2548 // Restore context register. 2560 // Restore context register.
2549 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2561 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2550 context()->Plug(rax); 2562 context()->Plug(rax);
2551 } 2563 }
2552 2564
(...skipping 24 matching lines...) Expand all
2577 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2589 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
2578 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. 2590 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
2579 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); 2591 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId());
2580 RecordJSReturnSite(expr); 2592 RecordJSReturnSite(expr);
2581 // Restore context register. 2593 // Restore context register.
2582 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2594 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2583 context()->DropAndPlug(1, rax); // Drop the key still on the stack. 2595 context()->DropAndPlug(1, rax); // Drop the key still on the stack.
2584 } 2596 }
2585 2597
2586 2598
2587 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2599 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2588 // Code common for calls using the call stub. 2600 // Code common for calls using the call stub.
2589 ZoneList<Expression*>* args = expr->arguments(); 2601 ZoneList<Expression*>* args = expr->arguments();
2590 int arg_count = args->length(); 2602 int arg_count = args->length();
2591 { PreservePositionScope scope(masm()->positions_recorder()); 2603 { PreservePositionScope scope(masm()->positions_recorder());
2592 for (int i = 0; i < arg_count; i++) { 2604 for (int i = 0; i < arg_count; i++) {
2593 VisitForStackValue(args->at(i)); 2605 VisitForStackValue(args->at(i));
2594 } 2606 }
2595 } 2607 }
2596 // Record source position for debugger. 2608 // Record source position for debugger.
2597 SetSourcePosition(expr->position()); 2609 SetSourcePosition(expr->position());
2598 2610
2599 // Record call targets in unoptimized code.
2600 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
2601 Handle<Object> uninitialized = 2611 Handle<Object> uninitialized =
2602 TypeFeedbackCells::UninitializedSentinel(isolate()); 2612 TypeFeedbackCells::UninitializedSentinel(isolate());
2603 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2613 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2604 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2614 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
2605 __ Move(rbx, cell); 2615 __ Move(rbx, cell);
2606 2616
2607 CallFunctionStub stub(arg_count, flags); 2617 // Record call targets in unoptimized code.
2618 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2608 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2619 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2609 __ CallStub(&stub, expr->CallFeedbackId()); 2620 __ CallStub(&stub, expr->CallFeedbackId());
2610 RecordJSReturnSite(expr); 2621 RecordJSReturnSite(expr);
2611 // Restore context register. 2622 // Restore context register.
2612 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2623 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2613 // Discard the function left on TOS. 2624 // Discard the function left on TOS.
2614 context()->DropAndPlug(1, rax); 2625 context()->DropAndPlug(1, rax);
2615 } 2626 }
2616 2627
2617 2628
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 // Push function. 2727 // Push function.
2717 __ push(rax); 2728 __ push(rax);
2718 // The receiver is implicitly the global receiver. Indicate this by 2729 // The receiver is implicitly the global receiver. Indicate this by
2719 // passing the hole to the call function stub. 2730 // passing the hole to the call function stub.
2720 __ PushRoot(Heap::kUndefinedValueRootIndex); 2731 __ PushRoot(Heap::kUndefinedValueRootIndex);
2721 __ bind(&call); 2732 __ bind(&call);
2722 } 2733 }
2723 2734
2724 // The receiver is either the global receiver or an object found by 2735 // The receiver is either the global receiver or an object found by
2725 // LoadContextSlot. 2736 // LoadContextSlot.
2726 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2737 EmitCallWithStub(expr);
2727 } else if (property != NULL) { 2738 } else if (property != NULL) {
2728 { PreservePositionScope scope(masm()->positions_recorder()); 2739 { PreservePositionScope scope(masm()->positions_recorder());
2729 VisitForStackValue(property->obj()); 2740 VisitForStackValue(property->obj());
2730 } 2741 }
2731 if (property->key()->IsPropertyName()) { 2742 if (property->key()->IsPropertyName()) {
2732 EmitCallWithIC(expr, 2743 EmitCallWithIC(expr,
2733 property->key()->AsLiteral()->value(), 2744 property->key()->AsLiteral()->value(),
2734 NOT_CONTEXTUAL); 2745 NOT_CONTEXTUAL);
2735 } else { 2746 } else {
2736 EmitKeyedCallWithIC(expr, property->key()); 2747 EmitKeyedCallWithIC(expr, property->key());
2737 } 2748 }
2738 } else { 2749 } else {
2739 // Call to an arbitrary expression not handled specially above. 2750 // Call to an arbitrary expression not handled specially above.
2740 { PreservePositionScope scope(masm()->positions_recorder()); 2751 { PreservePositionScope scope(masm()->positions_recorder());
2741 VisitForStackValue(callee); 2752 VisitForStackValue(callee);
2742 } 2753 }
2743 __ PushRoot(Heap::kUndefinedValueRootIndex); 2754 __ PushRoot(Heap::kUndefinedValueRootIndex);
2744 // Emit function call. 2755 // Emit function call.
2745 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2756 EmitCallWithStub(expr);
2746 } 2757 }
2747 2758
2748 #ifdef DEBUG 2759 #ifdef DEBUG
2749 // RecordJSReturnSite should have been called. 2760 // RecordJSReturnSite should have been called.
2750 ASSERT(expr->return_is_recorded_); 2761 ASSERT(expr->return_is_recorded_);
2751 #endif 2762 #endif
2752 } 2763 }
2753 2764
2754 2765
2755 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2766 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after
3660 3671
3661 Label runtime, done; 3672 Label runtime, done;
3662 // Check for non-function argument (including proxy). 3673 // Check for non-function argument (including proxy).
3663 __ JumpIfSmi(rax, &runtime); 3674 __ JumpIfSmi(rax, &runtime);
3664 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 3675 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
3665 __ j(not_equal, &runtime); 3676 __ j(not_equal, &runtime);
3666 3677
3667 // InvokeFunction requires the function in rdi. Move it in there. 3678 // InvokeFunction requires the function in rdi. Move it in there.
3668 __ movq(rdi, result_register()); 3679 __ movq(rdi, result_register());
3669 ParameterCount count(arg_count); 3680 ParameterCount count(arg_count);
3670 __ InvokeFunction(rdi, count, CALL_FUNCTION, 3681 __ InvokeFunction(rdi, count, CALL_FUNCTION, NullCallWrapper());
3671 NullCallWrapper(), CALL_AS_FUNCTION);
3672 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3682 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3673 __ jmp(&done); 3683 __ jmp(&done);
3674 3684
3675 __ bind(&runtime); 3685 __ bind(&runtime);
3676 __ push(rax); 3686 __ push(rax);
3677 __ CallRuntime(Runtime::kCall, args->length()); 3687 __ CallRuntime(Runtime::kCall, args->length());
3678 __ bind(&done); 3688 __ bind(&done);
3679 3689
3680 context()->Plug(rax); 3690 context()->Plug(rax);
3681 } 3691 }
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 4141
4132 // Push the arguments ("left-to-right"). 4142 // Push the arguments ("left-to-right").
4133 int arg_count = args->length(); 4143 int arg_count = args->length();
4134 for (int i = 0; i < arg_count; i++) { 4144 for (int i = 0; i < arg_count; i++) {
4135 VisitForStackValue(args->at(i)); 4145 VisitForStackValue(args->at(i));
4136 } 4146 }
4137 4147
4138 if (expr->is_jsruntime()) { 4148 if (expr->is_jsruntime()) {
4139 // Call the JS runtime function using a call IC. 4149 // Call the JS runtime function using a call IC.
4140 __ Move(rcx, expr->name()); 4150 __ Move(rcx, expr->name());
4141 ContextualMode mode = NOT_CONTEXTUAL; 4151 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count);
4142 Handle<Code> ic = 4152 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4143 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
4144 CallIC(ic, mode, expr->CallRuntimeFeedbackId());
4145 // Restore context register. 4153 // Restore context register.
4146 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4154 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
4147 } else { 4155 } else {
4148 __ CallRuntime(expr->function(), arg_count); 4156 __ CallRuntime(expr->function(), arg_count);
4149 } 4157 }
4150 context()->Plug(rax); 4158 context()->Plug(rax);
4151 } 4159 }
4152 4160
4153 4161
4154 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4162 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
4889 4897
4890 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4898 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4891 Assembler::target_address_at(call_target_address)); 4899 Assembler::target_address_at(call_target_address));
4892 return OSR_AFTER_STACK_CHECK; 4900 return OSR_AFTER_STACK_CHECK;
4893 } 4901 }
4894 4902
4895 4903
4896 } } // namespace v8::internal 4904 } } // namespace v8::internal
4897 4905
4898 #endif // V8_TARGET_ARCH_X64 4906 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698