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 |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
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 // TODO(X64): Remove stdio.h when compiler test is removed. | |
29 #include <stdio.h> | |
30 | |
31 #include "v8.h" | 28 #include "v8.h" |
32 | 29 |
33 #include "bootstrapper.h" | 30 #include "bootstrapper.h" |
34 #include "codegen-inl.h" | 31 #include "codegen-inl.h" |
35 #include "debug.h" | 32 #include "debug.h" |
36 #include "ic-inl.h" | 33 #include "ic-inl.h" |
37 #include "parser.h" | 34 #include "parser.h" |
38 #include "register-allocator-inl.h" | 35 #include "register-allocator-inl.h" |
39 #include "scopes.h" | 36 #include "scopes.h" |
40 | 37 |
41 // TODO(X64): Remove compiler.h when compiler test is removed. | |
42 #include "compiler.h" | |
43 | |
44 namespace v8 { | 38 namespace v8 { |
45 namespace internal { | 39 namespace internal { |
46 | 40 |
47 #define __ ACCESS_MASM(masm_) | 41 #define __ ACCESS_MASM(masm_) |
48 | 42 |
49 // ------------------------------------------------------------------------- | 43 // ------------------------------------------------------------------------- |
50 // Platform-specific DeferredCode functions. | 44 // Platform-specific DeferredCode functions. |
51 | 45 |
52 void DeferredCode::SaveRegisters() { | 46 void DeferredCode::SaveRegisters() { |
53 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { | 47 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 125 |
132 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); | 126 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); |
133 frame_->EmitPush(kScratchRegister); | 127 frame_->EmitPush(kScratchRegister); |
134 frame_->EmitPush(rsi); // The context is the second argument. | 128 frame_->EmitPush(rsi); // The context is the second argument. |
135 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); | 129 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); |
136 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); | 130 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); |
137 // Return value is ignored. | 131 // Return value is ignored. |
138 } | 132 } |
139 | 133 |
140 | 134 |
141 void CodeGenerator::TestCodeGenerator() { | |
142 // Compile a function from a string, and run it. | |
143 | |
144 // Set flags appropriately for this stage of implementation. | |
145 // TODO(X64): Make ic work, and stop disabling them. | |
146 // These settings stick - remove them when we don't want them anymore. | |
147 #ifdef DEBUG | |
148 FLAG_print_builtin_source = true; | |
149 FLAG_print_builtin_ast = true; | |
150 #endif | |
151 FLAG_use_ic = false; | |
152 | |
153 // Read the file "test.js" from the current directory, compile, and run it. | |
154 // If the file is not there, use a simple script embedded here instead. | |
155 Handle<String> test_script; | |
156 FILE* file = fopen("test.js", "rb"); | |
157 if (file == NULL) { | |
158 test_script = Factory::NewStringFromAscii(CStrVector( | |
159 "// Put all code in anonymous function to avoid global scope.\n" | |
160 "(function(){" | |
161 " var x = true ? 47 : 32;" | |
162 " return x;" | |
163 "})()")); | |
164 } else { | |
165 fseek(file, 0, SEEK_END); | |
166 int size = ftell(file); | |
167 rewind(file); | |
168 | |
169 char* chars = new char[size + 1]; | |
170 chars[size] = '\0'; | |
171 for (int i = 0; i < size;) { | |
172 int read = fread(&chars[i], 1, size - i, file); | |
173 i += read; | |
174 } | |
175 fclose(file); | |
176 test_script = Factory::NewStringFromAscii(CStrVector(chars)); | |
177 delete[] chars; | |
178 } | |
179 | |
180 Handle<JSFunction> test_function = Compiler::Compile( | |
181 test_script, | |
182 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), | |
183 0, | |
184 0, | |
185 NULL, | |
186 NULL); | |
187 | |
188 Code* code_object = test_function->code(); // Local for debugging ease. | |
189 USE(code_object); | |
190 | |
191 // Create a dummy function and context. | |
192 Handle<JSFunction> bridge = | |
193 Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value()); | |
194 Handle<Context> context = | |
195 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); | |
196 | |
197 test_function = Factory::NewFunctionFromBoilerplate( | |
198 test_function, | |
199 context); | |
200 | |
201 bool pending_exceptions; | |
202 Handle<Object> result = | |
203 Execution::Call(test_function, | |
204 Handle<Object>::cast(test_function), | |
205 0, | |
206 NULL, | |
207 &pending_exceptions); | |
208 // Function compiles and runs, but returns a JSFunction object. | |
209 #ifdef DEBUG | |
210 PrintF("Result of test function: "); | |
211 result->Print(); | |
212 #endif | |
213 } | |
214 | |
215 | |
216 void CodeGenerator::GenCode(FunctionLiteral* function) { | 135 void CodeGenerator::GenCode(FunctionLiteral* function) { |
217 // Record the position for debugging purposes. | 136 // Record the position for debugging purposes. |
218 CodeForFunctionPosition(function); | 137 CodeForFunctionPosition(function); |
219 ZoneList<Statement*>* body = function->body(); | 138 ZoneList<Statement*>* body = function->body(); |
220 | 139 |
221 // Initialize state. | 140 // Initialize state. |
222 ASSERT(scope_ == NULL); | 141 ASSERT(scope_ == NULL); |
223 scope_ = function->scope(); | 142 scope_ = function->scope(); |
224 ASSERT(allocator_ == NULL); | 143 ASSERT(allocator_ == NULL); |
225 RegisterAllocator register_allocator(this); | 144 RegisterAllocator register_allocator(this); |
(...skipping 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 // Get the property value off the stack. | 2139 // Get the property value off the stack. |
2221 Result prop_value = frame_->Pop(); | 2140 Result prop_value = frame_->Pop(); |
2222 prop_value.ToRegister(); | 2141 prop_value.ToRegister(); |
2223 | 2142 |
2224 // Fetch the array literal while leaving a copy on the stack and | 2143 // Fetch the array literal while leaving a copy on the stack and |
2225 // use it to get the elements array. | 2144 // use it to get the elements array. |
2226 frame_->Dup(); | 2145 frame_->Dup(); |
2227 Result elements = frame_->Pop(); | 2146 Result elements = frame_->Pop(); |
2228 elements.ToRegister(); | 2147 elements.ToRegister(); |
2229 frame_->Spill(elements.reg()); | 2148 frame_->Spill(elements.reg()); |
2230 // Get the elements array. | 2149 // Get the elements FixedArray. |
2231 __ movq(elements.reg(), | 2150 __ movq(elements.reg(), |
2232 FieldOperand(elements.reg(), JSObject::kElementsOffset)); | 2151 FieldOperand(elements.reg(), JSObject::kElementsOffset)); |
2233 | 2152 |
2234 // Write to the indexed properties array. | 2153 // Write to the indexed properties array. |
2235 int offset = i * kPointerSize + Array::kHeaderSize; | 2154 int offset = i * kPointerSize + FixedArray::kHeaderSize; |
2236 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); | 2155 __ movq(FieldOperand(elements.reg(), offset), prop_value.reg()); |
2237 | 2156 |
2238 // Update the write barrier for the array address. | 2157 // Update the write barrier for the array address. |
2239 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. | 2158 frame_->Spill(prop_value.reg()); // Overwritten by the write barrier. |
2240 Result scratch = allocator_->Allocate(); | 2159 Result scratch = allocator_->Allocate(); |
2241 ASSERT(scratch.is_valid()); | 2160 ASSERT(scratch.is_valid()); |
2242 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); | 2161 __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg()); |
2243 } | 2162 } |
2244 } | 2163 } |
2245 | 2164 |
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 | 3139 |
3221 } else if (check->Equals(Heap::object_symbol())) { | 3140 } else if (check->Equals(Heap::object_symbol())) { |
3222 __ testl(answer.reg(), Immediate(kSmiTagMask)); | 3141 __ testl(answer.reg(), Immediate(kSmiTagMask)); |
3223 destination()->false_target()->Branch(zero); | 3142 destination()->false_target()->Branch(zero); |
3224 __ Cmp(answer.reg(), Factory::null_value()); | 3143 __ Cmp(answer.reg(), Factory::null_value()); |
3225 destination()->true_target()->Branch(equal); | 3144 destination()->true_target()->Branch(equal); |
3226 | 3145 |
3227 // It can be an undetectable object. | 3146 // It can be an undetectable object. |
3228 __ movq(kScratchRegister, | 3147 __ movq(kScratchRegister, |
3229 FieldOperand(answer.reg(), HeapObject::kMapOffset)); | 3148 FieldOperand(answer.reg(), HeapObject::kMapOffset)); |
| 3149 __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset), |
| 3150 Immediate(1 << Map::kIsUndetectable)); |
| 3151 destination()->false_target()->Branch(not_zero); |
3230 __ movb(kScratchRegister, | 3152 __ movb(kScratchRegister, |
3231 FieldOperand(kScratchRegister, Map::kBitFieldOffset)); | 3153 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); |
3232 __ testb(kScratchRegister, Immediate(1 << Map::kIsUndetectable)); | |
3233 destination()->false_target()->Branch(not_zero); | |
3234 __ cmpb(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE)); | 3154 __ cmpb(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE)); |
3235 destination()->false_target()->Branch(below); | 3155 destination()->false_target()->Branch(below); |
3236 __ cmpb(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE)); | 3156 __ cmpb(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE)); |
3237 answer.Unuse(); | 3157 answer.Unuse(); |
3238 destination()->Split(below_equal); | 3158 destination()->Split(below_equal); |
3239 } else { | 3159 } else { |
3240 // Uncommon case: typeof testing against a string literal that is | 3160 // Uncommon case: typeof testing against a string literal that is |
3241 // never returned from the typeof operator. | 3161 // never returned from the typeof operator. |
3242 answer.Unuse(); | 3162 answer.Unuse(); |
3243 destination()->Goto(false); | 3163 destination()->Goto(false); |
(...skipping 3486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6730 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 6650 __ movq(rax, Operand(rsp, 1 * kPointerSize)); |
6731 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 6651 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
6732 break; | 6652 break; |
6733 } | 6653 } |
6734 default: UNREACHABLE(); break; | 6654 default: UNREACHABLE(); break; |
6735 } | 6655 } |
6736 | 6656 |
6737 // If all else fails, use the runtime system to get the correct | 6657 // If all else fails, use the runtime system to get the correct |
6738 // result. | 6658 // result. |
6739 __ bind(&call_runtime); | 6659 __ bind(&call_runtime); |
6740 // Disable builtin-calls until JS builtins can compile and run. | |
6741 __ Abort("Disabled until builtins compile and run."); | |
6742 switch (op_) { | 6660 switch (op_) { |
6743 case Token::ADD: | 6661 case Token::ADD: |
6744 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 6662 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
6745 break; | 6663 break; |
6746 case Token::SUB: | 6664 case Token::SUB: |
6747 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 6665 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
6748 break; | 6666 break; |
6749 case Token::MUL: | 6667 case Token::MUL: |
6750 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 6668 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
6751 break; | 6669 break; |
(...skipping 30 matching lines...) Expand all Loading... |
6782 int CompareStub::MinorKey() { | 6700 int CompareStub::MinorKey() { |
6783 // Encode the two parameters in a unique 16 bit value. | 6701 // Encode the two parameters in a unique 16 bit value. |
6784 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 6702 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
6785 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 6703 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
6786 } | 6704 } |
6787 | 6705 |
6788 | 6706 |
6789 #undef __ | 6707 #undef __ |
6790 | 6708 |
6791 } } // namespace v8::internal | 6709 } } // namespace v8::internal |
OLD | NEW |