| 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 |