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 12 matching lines...) Expand all Loading... |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 | 28 |
29 #include "v8.h" | 29 #include "v8.h" |
30 #include "macro-assembler.h" | 30 #include "macro-assembler.h" |
31 #include "register-allocator-inl.h" | 31 #include "register-allocator-inl.h" |
32 #include "codegen.h" | 32 #include "codegen.h" |
| 33 // TEST |
| 34 #include "compiler.h" |
33 | 35 |
34 namespace v8 { | 36 namespace v8 { |
35 namespace internal { | 37 namespace internal { |
36 | 38 |
37 // ------------------------------------------------------------------------- | 39 // ------------------------------------------------------------------------- |
38 // Platform-specific DeferredCode functions. | 40 // Platform-specific DeferredCode functions. |
39 | 41 |
40 void DeferredCode::SaveRegisters() { UNIMPLEMENTED(); } | 42 void DeferredCode::SaveRegisters() { UNIMPLEMENTED(); } |
41 | 43 |
42 void DeferredCode::RestoreRegisters() { UNIMPLEMENTED(); } | 44 void DeferredCode::RestoreRegisters() { UNIMPLEMENTED(); } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 92 } |
91 | 93 |
92 #define __ ACCESS_MASM(masm_) | 94 #define __ ACCESS_MASM(masm_) |
93 | 95 |
94 | 96 |
95 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { | 97 void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) { |
96 UNIMPLEMENTED(); | 98 UNIMPLEMENTED(); |
97 } | 99 } |
98 | 100 |
99 void CodeGenerator::TestCodeGenerator() { | 101 void CodeGenerator::TestCodeGenerator() { |
100 // Generate code. | 102 // Compile a function from a string, and run it. |
101 ZoneScope zone_scope(DELETE_ON_EXIT); | 103 Handle<JSFunction> test_function = Compiler::Compile( |
102 const int initial_buffer_size = 4 * KB; | 104 Factory::NewStringFromAscii(CStrVector("42")), |
103 CodeGenerator cgen(initial_buffer_size, NULL, false); | 105 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), |
104 CodeGeneratorScope scope(&cgen); | 106 0, |
105 Scope dummy_scope; | 107 0, |
106 cgen.scope_ = &dummy_scope; | 108 NULL, |
107 cgen.GenCode(NULL); | 109 NULL); |
108 | 110 |
109 CodeDesc desc; | 111 Code* code_object = test_function->code(); // Local for debugging ease. |
110 cgen.masm()->GetCode(&desc); | 112 USE(code_object); |
| 113 |
| 114 // Create a dummy function and context. |
| 115 Handle<JSFunction> bridge = |
| 116 Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value()); |
| 117 Handle<Context> context = |
| 118 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); |
| 119 |
| 120 test_function = Factory::NewFunctionFromBoilerplate( |
| 121 test_function, |
| 122 context); |
| 123 |
| 124 bool pending_exceptions; |
| 125 Handle<Object> result = |
| 126 Execution::Call(test_function, |
| 127 Handle<Object>::cast(test_function), |
| 128 0, |
| 129 NULL, |
| 130 &pending_exceptions); |
| 131 CHECK(result->IsSmi()); |
| 132 CHECK_EQ(42, Smi::cast(*result)->value()); |
111 } | 133 } |
112 | 134 |
113 | 135 |
114 void CodeGenerator::GenCode(FunctionLiteral* function) { | 136 void CodeGenerator::GenCode(FunctionLiteral* function) { |
115 if (function != NULL) { | 137 // Record the position for debugging purposes. |
116 CodeForFunctionPosition(function); | 138 CodeForFunctionPosition(function); |
117 // ASSERT(scope_ == NULL); | 139 // ZoneList<Statement*>* body = fun->body(); |
118 // scope_ = function->scope(); | |
119 __ int3(); // UNIMPLEMENTED | |
120 } else { | |
121 // GenCode Implementation under construction. Run by TestCodeGenerator | |
122 // with a == NULL. | |
123 // Everything guarded by if (function) should be run, unguarded, | |
124 // once testing is over. | |
125 // Record the position for debugging purposes. | |
126 if (function) { | |
127 CodeForFunctionPosition(function); | |
128 } | |
129 // ZoneList<Statement*>* body = fun->body(); | |
130 | 140 |
131 // Initialize state. | 141 // Initialize state. |
132 // While testing, scope is set in cgen before calling GenCode(). | 142 ASSERT(scope_ == NULL); |
133 if (function) { | 143 scope_ = function->scope(); |
134 ASSERT(scope_ == NULL); | 144 ASSERT(allocator_ == NULL); |
135 scope_ = function->scope(); | 145 RegisterAllocator register_allocator(this); |
136 } | 146 allocator_ = ®ister_allocator; |
137 ASSERT(allocator_ == NULL); | 147 ASSERT(frame_ == NULL); |
138 RegisterAllocator register_allocator(this); | 148 frame_ = new VirtualFrame(); |
139 allocator_ = ®ister_allocator; | 149 set_in_spilled_code(false); |
140 ASSERT(frame_ == NULL); | |
141 frame_ = new VirtualFrame(); | |
142 set_in_spilled_code(false); | |
143 | 150 |
144 // Adjust for function-level loop nesting. | 151 // Adjust for function-level loop nesting. |
145 // loop_nesting_ += fun->loop_nesting(); | 152 loop_nesting_ += function->loop_nesting(); |
146 | 153 |
147 JumpTarget::set_compiling_deferred_code(false); | 154 JumpTarget::set_compiling_deferred_code(false); |
148 | 155 |
149 #ifdef DEBUG | 156 #ifdef DEBUG |
150 if (strlen(FLAG_stop_at) > 0 && | 157 if (strlen(FLAG_stop_at) > 0 && |
151 // fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 158 // fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
152 false) { | 159 false) { |
153 frame_->SpillAll(); | 160 frame_->SpillAll(); |
154 __ int3(); | 161 __ int3(); |
155 } | 162 } |
156 #endif | 163 #endif |
157 | 164 |
158 // New scope to get automatic timing calculation. | 165 // New scope to get automatic timing calculation. |
159 { // NOLINT | 166 { // NOLINT |
160 HistogramTimerScope codegen_timer(&Counters::code_generation); | 167 HistogramTimerScope codegen_timer(&Counters::code_generation); |
161 CodeGenState state(this); | 168 CodeGenState state(this); |
162 | 169 |
163 // Entry: | 170 // Entry: |
164 // Stack: receiver, arguments, return address. | 171 // Stack: receiver, arguments, return address. |
165 // ebp: caller's frame pointer | 172 // ebp: caller's frame pointer |
166 // esp: stack pointer | 173 // esp: stack pointer |
167 // edi: called JS function | 174 // edi: called JS function |
168 // esi: callee's context | 175 // esi: callee's context |
169 allocator_->Initialize(); | 176 allocator_->Initialize(); |
170 frame_->Enter(); | 177 frame_->Enter(); |
171 | 178 |
172 __ movq(rax, Immediate(0x2a)); | 179 Result return_register = allocator_->Allocate(rax); |
173 __ Ret(); | 180 |
174 } | 181 __ movq(return_register.reg(), Immediate(0x54)); // Smi 42 |
| 182 |
| 183 GenerateReturnSequence(&return_register); |
175 } | 184 } |
176 } | 185 } |
177 | 186 |
| 187 void CodeGenerator::GenerateReturnSequence(Result* return_value) { |
| 188 // The return value is a live (but not currently reference counted) |
| 189 // reference to rax. This is safe because the current frame does not |
| 190 // contain a reference to rax (it is prepared for the return by spilling |
| 191 // all registers). |
| 192 if (FLAG_trace) { |
| 193 frame_->Push(return_value); |
| 194 // *return_value = frame_->CallRuntime(Runtime::kTraceExit, 1); |
| 195 } |
| 196 return_value->ToRegister(rax); |
| 197 |
| 198 // Add a label for checking the size of the code used for returning. |
| 199 Label check_exit_codesize; |
| 200 masm_->bind(&check_exit_codesize); |
| 201 |
| 202 // Leave the frame and return popping the arguments and the |
| 203 // receiver. |
| 204 frame_->Exit(); |
| 205 masm_->ret((scope_->num_parameters() + 1) * kPointerSize); |
| 206 DeleteFrame(); |
| 207 |
| 208 // Check that the size of the code used for returning matches what is |
| 209 // expected by the debugger. |
| 210 // ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, |
| 211 // masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); |
| 212 } |
| 213 |
| 214 |
178 void CodeGenerator::GenerateFastCaseSwitchJumpTable(SwitchStatement* a, | 215 void CodeGenerator::GenerateFastCaseSwitchJumpTable(SwitchStatement* a, |
179 int b, | 216 int b, |
180 int c, | 217 int c, |
181 Label* d, | 218 Label* d, |
182 Vector<Label*> e, | 219 Vector<Label*> e, |
183 Vector<Label> f) { | 220 Vector<Label> f) { |
184 UNIMPLEMENTED(); | 221 UNIMPLEMENTED(); |
185 } | 222 } |
186 | 223 |
187 void CodeGenerator::VisitStatements(ZoneList<Statement*>* a) { | 224 void CodeGenerator::VisitStatements(ZoneList<Statement*>* a) { |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 | 777 |
741 // Restore frame pointer and return. | 778 // Restore frame pointer and return. |
742 __ pop(rbp); | 779 __ pop(rbp); |
743 __ ret(0); | 780 __ ret(0); |
744 } | 781 } |
745 | 782 |
746 | 783 |
747 #undef __ | 784 #undef __ |
748 | 785 |
749 } } // namespace v8::internal | 786 } } // namespace v8::internal |
OLD | NEW |