OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // The live registers are: | 44 // The live registers are: |
45 // o rdi: the JS function object being called (ie, ourselves) | 45 // o rdi: the JS function object being called (ie, ourselves) |
46 // o rsi: our context | 46 // o rsi: our context |
47 // o rbp: our caller's frame pointer | 47 // o rbp: our caller's frame pointer |
48 // o rsp: stack pointer (pointing to return address) | 48 // o rsp: stack pointer (pointing to return address) |
49 // | 49 // |
50 // The function builds a JS frame. Please see JavaScriptFrameConstants in | 50 // The function builds a JS frame. Please see JavaScriptFrameConstants in |
51 // frames-x64.h for its layout. | 51 // frames-x64.h for its layout. |
52 void FastCodeGenerator::Generate(FunctionLiteral* fun) { | 52 void FastCodeGenerator::Generate(FunctionLiteral* fun) { |
53 function_ = fun; | 53 function_ = fun; |
| 54 SetFunctionPosition(fun); |
54 | 55 |
55 __ push(rbp); // Caller's frame pointer. | 56 __ push(rbp); // Caller's frame pointer. |
56 __ movq(rbp, rsp); | 57 __ movq(rbp, rsp); |
57 __ push(rsi); // Callee's context. | 58 __ push(rsi); // Callee's context. |
58 __ push(rdi); // Callee's JS Function. | 59 __ push(rdi); // Callee's JS Function. |
59 | 60 |
60 { Comment cmnt(masm_, "[ Allocate locals"); | 61 { Comment cmnt(masm_, "[ Allocate locals"); |
61 int locals_count = fun->scope()->num_stack_slots(); | 62 int locals_count = fun->scope()->num_stack_slots(); |
62 for (int i = 0; i < locals_count; i++) { | 63 for (int i = 0; i < locals_count; i++) { |
63 __ PushRoot(Heap::kUndefinedValueRootIndex); | 64 __ PushRoot(Heap::kUndefinedValueRootIndex); |
(...skipping 10 matching lines...) Expand all Loading... |
74 } | 75 } |
75 | 76 |
76 { Comment cmnt(masm_, "[ Body"); | 77 { Comment cmnt(masm_, "[ Body"); |
77 VisitStatements(fun->body()); | 78 VisitStatements(fun->body()); |
78 } | 79 } |
79 | 80 |
80 { Comment cmnt(masm_, "[ return <undefined>;"); | 81 { Comment cmnt(masm_, "[ return <undefined>;"); |
81 // Emit a 'return undefined' in case control fell off the end of the | 82 // Emit a 'return undefined' in case control fell off the end of the |
82 // body. | 83 // body. |
83 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 84 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
| 85 SetReturnPosition(fun); |
84 __ RecordJSReturn(); | 86 __ RecordJSReturn(); |
85 // Do not use the leave instruction here because it is too short to | 87 // Do not use the leave instruction here because it is too short to |
86 // patch with the code required by the debugger. | 88 // patch with the code required by the debugger. |
87 __ movq(rsp, rbp); | 89 __ movq(rsp, rbp); |
88 __ pop(rbp); | 90 __ pop(rbp); |
89 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); | 91 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); |
90 #ifdef ENABLE_DEBUGGER_SUPPORT | 92 #ifdef ENABLE_DEBUGGER_SUPPORT |
91 // Add padding that will be overwritten by a debugger breakpoint. We | 93 // Add padding that will be overwritten by a debugger breakpoint. We |
92 // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 | 94 // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7 |
93 // (3 + 1 + 3). | 95 // (3 + 1 + 3). |
94 const int kPadding = Debug::kX64JSReturnSequenceLength - 7; | 96 const int kPadding = Debug::kX64JSReturnSequenceLength - 7; |
95 for (int i = 0; i < kPadding; ++i) { | 97 for (int i = 0; i < kPadding; ++i) { |
96 masm_->int3(); | 98 masm_->int3(); |
97 } | 99 } |
98 #endif | 100 #endif |
99 } | 101 } |
100 } | 102 } |
101 | 103 |
102 | 104 |
103 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 105 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
104 Comment cmnt(masm_, "[ ExpressionStatement"); | 106 Comment cmnt(masm_, "[ ExpressionStatement"); |
| 107 SetStatementPosition(stmt); |
105 Visit(stmt->expression()); | 108 Visit(stmt->expression()); |
106 __ pop(rax); | 109 __ pop(rax); |
107 } | 110 } |
108 | 111 |
109 | 112 |
110 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 113 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
111 Comment cmnt(masm_, "[ ReturnStatement"); | 114 Comment cmnt(masm_, "[ ReturnStatement"); |
| 115 SetStatementPosition(stmt); |
112 Visit(stmt->expression()); | 116 Visit(stmt->expression()); |
113 __ pop(rax); | 117 __ pop(rax); |
114 __ RecordJSReturn(); | 118 __ RecordJSReturn(); |
115 // Do not use the leave instruction here because it is too short to | 119 // Do not use the leave instruction here because it is too short to |
116 // patch with the code required by the debugger. | 120 // patch with the code required by the debugger. |
117 __ movq(rsp, rbp); | 121 __ movq(rsp, rbp); |
118 __ pop(rbp); | 122 __ pop(rbp); |
119 __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); | 123 __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); |
120 #ifdef ENABLE_DEBUGGER_SUPPORT | 124 #ifdef ENABLE_DEBUGGER_SUPPORT |
121 // Add padding that will be overwritten by a debugger breakpoint. We | 125 // Add padding that will be overwritten by a debugger breakpoint. We |
(...skipping 26 matching lines...) Expand all Loading... |
148 Visit(expr->value()); | 152 Visit(expr->value()); |
149 | 153 |
150 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 154 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
151 ASSERT(var != NULL && var->slot() != NULL); | 155 ASSERT(var != NULL && var->slot() != NULL); |
152 __ movq(rax, Operand(rsp, 0)); | 156 __ movq(rax, Operand(rsp, 0)); |
153 __ movq(Operand(rbp, SlotOffset(var->slot())), rax); | 157 __ movq(Operand(rbp, SlotOffset(var->slot())), rax); |
154 } | 158 } |
155 | 159 |
156 | 160 |
157 } } // namespace v8::internal | 161 } } // namespace v8::internal |
OLD | NEW |