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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 // o rsi: our context | 111 // o rsi: our context |
112 // o rbp: our caller's frame pointer | 112 // o rbp: our caller's frame pointer |
113 // o rsp: stack pointer (pointing to return address) | 113 // o rsp: stack pointer (pointing to return address) |
114 // | 114 // |
115 // The function builds a JS frame. Please see JavaScriptFrameConstants in | 115 // The function builds a JS frame. Please see JavaScriptFrameConstants in |
116 // frames-x64.h for its layout. | 116 // frames-x64.h for its layout. |
117 void FullCodeGenerator::Generate() { | 117 void FullCodeGenerator::Generate() { |
118 CompilationInfo* info = info_; | 118 CompilationInfo* info = info_; |
119 handler_table_ = | 119 handler_table_ = |
120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); | 120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); |
121 profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( | 121 profiling_counter_ = isolate()->factory()->NewCell( |
122 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); | 122 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); |
123 SetFunctionPosition(function()); | 123 SetFunctionPosition(function()); |
124 Comment cmnt(masm_, "[ function compiled by full code generator"); | 124 Comment cmnt(masm_, "[ function compiled by full code generator"); |
125 | 125 |
126 ProfileEntryHookStub::MaybeCallEntryHook(masm_); | 126 ProfileEntryHookStub::MaybeCallEntryHook(masm_); |
127 | 127 |
128 #ifdef DEBUG | 128 #ifdef DEBUG |
129 if (strlen(FLAG_stop_at) > 0 && | 129 if (strlen(FLAG_stop_at) > 0 && |
130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
131 __ int3(); | 131 __ int3(); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 301 } |
302 | 302 |
303 | 303 |
304 void FullCodeGenerator::ClearAccumulator() { | 304 void FullCodeGenerator::ClearAccumulator() { |
305 __ Set(rax, 0); | 305 __ Set(rax, 0); |
306 } | 306 } |
307 | 307 |
308 | 308 |
309 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { | 309 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { |
310 __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); | 310 __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); |
311 __ SmiAddConstant(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 311 __ SmiAddConstant(FieldOperand(rbx, Cell::kValueOffset), |
312 Smi::FromInt(-delta)); | 312 Smi::FromInt(-delta)); |
313 } | 313 } |
314 | 314 |
315 | 315 |
316 void FullCodeGenerator::EmitProfilingCounterReset() { | 316 void FullCodeGenerator::EmitProfilingCounterReset() { |
317 int reset_value = FLAG_interrupt_budget; | 317 int reset_value = FLAG_interrupt_budget; |
318 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { | 318 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { |
319 // Self-optimization is a one-off thing; if it fails, don't try again. | 319 // Self-optimization is a one-off thing; if it fails, don't try again. |
320 reset_value = Smi::kMaxValue; | 320 reset_value = Smi::kMaxValue; |
321 } | 321 } |
322 __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); | 322 __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); |
323 __ movq(kScratchRegister, | 323 __ movq(kScratchRegister, |
324 reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)), | 324 reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)), |
325 RelocInfo::NONE64); | 325 RelocInfo::NONE64); |
326 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 326 __ movq(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister); |
327 kScratchRegister); | |
328 } | 327 } |
329 | 328 |
330 | 329 |
331 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, | 330 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, |
332 Label* back_edge_target) { | 331 Label* back_edge_target) { |
333 Comment cmnt(masm_, "[ Back edge bookkeeping"); | 332 Comment cmnt(masm_, "[ Back edge bookkeeping"); |
334 Label ok; | 333 Label ok; |
335 | 334 |
336 int weight = 1; | 335 int weight = 1; |
337 if (FLAG_weighted_back_edges) { | 336 if (FLAG_weighted_back_edges) { |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 __ jmp(&loop); | 1120 __ jmp(&loop); |
1122 | 1121 |
1123 __ bind(&no_descriptors); | 1122 __ bind(&no_descriptors); |
1124 __ addq(rsp, Immediate(kPointerSize)); | 1123 __ addq(rsp, Immediate(kPointerSize)); |
1125 __ jmp(&exit); | 1124 __ jmp(&exit); |
1126 | 1125 |
1127 // We got a fixed array in register rax. Iterate through that. | 1126 // We got a fixed array in register rax. Iterate through that. |
1128 Label non_proxy; | 1127 Label non_proxy; |
1129 __ bind(&fixed_array); | 1128 __ bind(&fixed_array); |
1130 | 1129 |
1131 Handle<JSGlobalPropertyCell> cell = | 1130 Handle<Cell> cell = isolate()->factory()->NewCell( |
1132 isolate()->factory()->NewJSGlobalPropertyCell( | 1131 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), |
1133 Handle<Object>( | 1132 isolate())); |
1134 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), | |
1135 isolate())); | |
1136 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); | 1133 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); |
1137 __ LoadHeapObject(rbx, cell); | 1134 __ LoadHeapObject(rbx, cell); |
1138 __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 1135 __ Move(FieldOperand(rbx, Cell::kValueOffset), |
1139 Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)); | 1136 Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)); |
1140 | 1137 |
1141 __ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check | 1138 __ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check |
1142 __ movq(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object | 1139 __ movq(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object |
1143 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1140 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
1144 __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); | 1141 __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); |
1145 __ j(above, &non_proxy); | 1142 __ j(above, &non_proxy); |
1146 __ Move(rbx, Smi::FromInt(0)); // Zero indicates proxy | 1143 __ Move(rbx, Smi::FromInt(0)); // Zero indicates proxy |
1147 __ bind(&non_proxy); | 1144 __ bind(&non_proxy); |
1148 __ push(rbx); // Smi | 1145 __ push(rbx); // Smi |
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2613 VisitForStackValue(args->at(i)); | 2610 VisitForStackValue(args->at(i)); |
2614 } | 2611 } |
2615 } | 2612 } |
2616 // Record source position for debugger. | 2613 // Record source position for debugger. |
2617 SetSourcePosition(expr->position()); | 2614 SetSourcePosition(expr->position()); |
2618 | 2615 |
2619 // Record call targets in unoptimized code. | 2616 // Record call targets in unoptimized code. |
2620 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2617 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
2621 Handle<Object> uninitialized = | 2618 Handle<Object> uninitialized = |
2622 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2619 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2623 Handle<JSGlobalPropertyCell> cell = | 2620 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); |
2624 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | |
2625 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); | 2621 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
2626 __ Move(rbx, cell); | 2622 __ Move(rbx, cell); |
2627 | 2623 |
2628 CallFunctionStub stub(arg_count, flags); | 2624 CallFunctionStub stub(arg_count, flags); |
2629 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2625 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2630 __ CallStub(&stub, expr->CallFeedbackId()); | 2626 __ CallStub(&stub, expr->CallFeedbackId()); |
2631 RecordJSReturnSite(expr); | 2627 RecordJSReturnSite(expr); |
2632 // Restore context register. | 2628 // Restore context register. |
2633 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2629 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2634 // Discard the function left on TOS. | 2630 // Discard the function left on TOS. |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2797 // constructor invocation. | 2793 // constructor invocation. |
2798 SetSourcePosition(expr->position()); | 2794 SetSourcePosition(expr->position()); |
2799 | 2795 |
2800 // Load function and argument count into rdi and rax. | 2796 // Load function and argument count into rdi and rax. |
2801 __ Set(rax, arg_count); | 2797 __ Set(rax, arg_count); |
2802 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); | 2798 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); |
2803 | 2799 |
2804 // Record call targets in unoptimized code, but not in the snapshot. | 2800 // Record call targets in unoptimized code, but not in the snapshot. |
2805 Handle<Object> uninitialized = | 2801 Handle<Object> uninitialized = |
2806 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2802 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2807 Handle<JSGlobalPropertyCell> cell = | 2803 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); |
2808 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | |
2809 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); | 2804 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); |
2810 __ Move(rbx, cell); | 2805 __ Move(rbx, cell); |
2811 | 2806 |
2812 CallConstructStub stub(RECORD_CALL_TARGET); | 2807 CallConstructStub stub(RECORD_CALL_TARGET); |
2813 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2808 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
2814 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2809 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2815 context()->Plug(rax); | 2810 context()->Plug(rax); |
2816 } | 2811 } |
2817 | 2812 |
2818 | 2813 |
(...skipping 2093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4912 *context_length = 0; | 4907 *context_length = 0; |
4913 return previous_; | 4908 return previous_; |
4914 } | 4909 } |
4915 | 4910 |
4916 | 4911 |
4917 #undef __ | 4912 #undef __ |
4918 | 4913 |
4919 } } // namespace v8::internal | 4914 } } // namespace v8::internal |
4920 | 4915 |
4921 #endif // V8_TARGET_ARCH_X64 | 4916 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |