Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: src/arm/virtual-frame-arm.cc

Issue 92068: Move backend specific files to separate directories. (Closed)
Patch Set: Added CPPPATH flag and made all includes use same base path. Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/virtual-frame-arm.h ('k') | src/assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
28 #include "v8.h"
29
30 #include "codegen-inl.h"
31 #include "register-allocator-inl.h"
32 #include "scopes.h"
33
34 namespace v8 { namespace internal {
35
36 // -------------------------------------------------------------------------
37 // VirtualFrame implementation.
38
39 #define __ ACCESS_MASM(masm_)
40
41
42 // On entry to a function, the virtual frame already contains the
43 // receiver and the parameters. All initial frame elements are in
44 // memory.
45 VirtualFrame::VirtualFrame(CodeGenerator* cgen)
46 : cgen_(cgen),
47 masm_(cgen->masm()),
48 elements_(cgen->scope()->num_parameters()
49 + cgen->scope()->num_stack_slots()
50 + kPreallocatedElements),
51 parameter_count_(cgen->scope()->num_parameters()),
52 local_count_(0),
53 stack_pointer_(parameter_count_), // 0-based index of TOS.
54 frame_pointer_(kIllegalIndex) {
55 for (int i = 0; i < parameter_count_ + 1; i++) {
56 elements_.Add(FrameElement::MemoryElement());
57 }
58 for (int i = 0; i < kNumRegisters; i++) {
59 register_locations_[i] = kIllegalIndex;
60 }
61 }
62
63
64 void VirtualFrame::SyncElementBelowStackPointer(int index) {
65 UNREACHABLE();
66 }
67
68
69 void VirtualFrame::SyncElementByPushing(int index) {
70 UNREACHABLE();
71 }
72
73
74 void VirtualFrame::MergeTo(VirtualFrame* expected) {
75 Comment cmnt(masm_, "[ Merge frame");
76 // We should always be merging the code generator's current frame to an
77 // expected frame.
78 ASSERT(cgen_->frame() == this);
79
80 // Adjust the stack pointer upward (toward the top of the virtual
81 // frame) if necessary.
82 if (stack_pointer_ < expected->stack_pointer_) {
83 int difference = expected->stack_pointer_ - stack_pointer_;
84 stack_pointer_ = expected->stack_pointer_;
85 __ sub(sp, sp, Operand(difference * kPointerSize));
86 }
87
88 MergeMoveRegistersToMemory(expected);
89 MergeMoveRegistersToRegisters(expected);
90 MergeMoveMemoryToRegisters(expected);
91
92 // Fix any sync bit problems from the bottom-up, stopping when we
93 // hit the stack pointer or the top of the frame if the stack
94 // pointer is floating above the frame.
95 int limit = Min(stack_pointer_, elements_.length() - 1);
96 for (int i = 0; i <= limit; i++) {
97 FrameElement source = elements_[i];
98 FrameElement target = expected->elements_[i];
99 if (source.is_synced() && !target.is_synced()) {
100 elements_[i].clear_sync();
101 } else if (!source.is_synced() && target.is_synced()) {
102 SyncElementAt(i);
103 }
104 }
105
106 // Adjust the stack point downard if necessary.
107 if (stack_pointer_ > expected->stack_pointer_) {
108 int difference = stack_pointer_ - expected->stack_pointer_;
109 stack_pointer_ = expected->stack_pointer_;
110 __ add(sp, sp, Operand(difference * kPointerSize));
111 }
112
113 // At this point, the frames should be identical.
114 ASSERT(Equals(expected));
115 }
116
117
118 void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) {
119 ASSERT(stack_pointer_ >= expected->stack_pointer_);
120
121 // Move registers, constants, and copies to memory. Perform moves
122 // from the top downward in the frame in order to leave the backing
123 // stores of copies in registers.
124 // On ARM, all elements are in memory.
125
126 #ifdef DEBUG
127 int start = Min(stack_pointer_, elements_.length() - 1);
128 for (int i = start; i >= 0; i--) {
129 ASSERT(elements_[i].is_memory());
130 ASSERT(expected->elements_[i].is_memory());
131 }
132 #endif
133 }
134
135
136 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
137 }
138
139
140 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) {
141 }
142
143
144 void VirtualFrame::Enter() {
145 Comment cmnt(masm_, "[ Enter JS frame");
146
147 #ifdef DEBUG
148 // Verify that r1 contains a JS function. The following code relies
149 // on r2 being available for use.
150 { Label map_check, done;
151 __ tst(r1, Operand(kSmiTagMask));
152 __ b(ne, &map_check);
153 __ stop("VirtualFrame::Enter - r1 is not a function (smi check).");
154 __ bind(&map_check);
155 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
156 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
157 __ cmp(r2, Operand(JS_FUNCTION_TYPE));
158 __ b(eq, &done);
159 __ stop("VirtualFrame::Enter - r1 is not a function (map check).");
160 __ bind(&done);
161 }
162 #endif // DEBUG
163
164 // We are about to push four values to the frame.
165 Adjust(4);
166 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
167 // Adjust FP to point to saved FP.
168 frame_pointer_ = elements_.length() - 2;
169 __ add(fp, sp, Operand(2 * kPointerSize));
170 cgen_->allocator()->Unuse(r1);
171 cgen_->allocator()->Unuse(lr);
172 }
173
174
175 void VirtualFrame::Exit() {
176 Comment cmnt(masm_, "[ Exit JS frame");
177 // Drop the execution stack down to the frame pointer and restore the caller
178 // frame pointer and return address.
179 __ mov(sp, fp);
180 __ ldm(ia_w, sp, fp.bit() | lr.bit());
181 }
182
183
184 void VirtualFrame::AllocateStackSlots(int count) {
185 ASSERT(height() == 0);
186 local_count_ = count;
187 Adjust(count);
188 if (count > 0) {
189 Comment cmnt(masm_, "[ Allocate space for locals");
190 // Initialize stack slots with 'undefined' value.
191 __ mov(ip, Operand(Factory::undefined_value()));
192 for (int i = 0; i < count; i++) {
193 __ push(ip);
194 }
195 }
196 }
197
198
199 void VirtualFrame::SaveContextRegister() {
200 UNIMPLEMENTED();
201 }
202
203
204 void VirtualFrame::RestoreContextRegister() {
205 UNIMPLEMENTED();
206 }
207
208
209 void VirtualFrame::PushReceiverSlotAddress() {
210 UNIMPLEMENTED();
211 }
212
213
214 int VirtualFrame::InvalidateFrameSlotAt(int index) {
215 UNIMPLEMENTED();
216 return kIllegalIndex;
217 }
218
219
220 void VirtualFrame::TakeFrameSlotAt(int index) {
221 UNIMPLEMENTED();
222 }
223
224
225 void VirtualFrame::StoreToFrameSlotAt(int index) {
226 UNIMPLEMENTED();
227 }
228
229
230 void VirtualFrame::PushTryHandler(HandlerType type) {
231 // Grow the expression stack by handler size less one (the return address
232 // is already pushed by a call instruction).
233 Adjust(kHandlerSize - 1);
234 __ PushTryHandler(IN_JAVASCRIPT, type);
235 }
236
237
238 Result VirtualFrame::RawCallStub(CodeStub* stub) {
239 ASSERT(cgen_->HasValidEntryRegisters());
240 __ CallStub(stub);
241 Result result = cgen_->allocator()->Allocate(r0);
242 ASSERT(result.is_valid());
243 return result;
244 }
245
246
247 Result VirtualFrame::CallStub(CodeStub* stub, Result* arg) {
248 PrepareForCall(0, 0);
249 arg->Unuse();
250 return RawCallStub(stub);
251 }
252
253
254 Result VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) {
255 PrepareForCall(0, 0);
256 arg0->Unuse();
257 arg1->Unuse();
258 return RawCallStub(stub);
259 }
260
261
262 Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
263 PrepareForCall(arg_count, arg_count);
264 ASSERT(cgen_->HasValidEntryRegisters());
265 __ CallRuntime(f, arg_count);
266 Result result = cgen_->allocator()->Allocate(r0);
267 ASSERT(result.is_valid());
268 return result;
269 }
270
271
272 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
273 PrepareForCall(arg_count, arg_count);
274 ASSERT(cgen_->HasValidEntryRegisters());
275 __ CallRuntime(id, arg_count);
276 Result result = cgen_->allocator()->Allocate(r0);
277 ASSERT(result.is_valid());
278 return result;
279 }
280
281
282 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
283 InvokeJSFlags flags,
284 Result* arg_count_register,
285 int arg_count) {
286 ASSERT(arg_count_register->reg().is(r0));
287 PrepareForCall(arg_count, arg_count);
288 arg_count_register->Unuse();
289 __ InvokeBuiltin(id, flags);
290 Result result = cgen_->allocator()->Allocate(r0);
291 return result;
292 }
293
294
295 Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
296 RelocInfo::Mode rmode) {
297 ASSERT(cgen_->HasValidEntryRegisters());
298 __ Call(code, rmode);
299 Result result = cgen_->allocator()->Allocate(r0);
300 ASSERT(result.is_valid());
301 return result;
302 }
303
304
305 Result VirtualFrame::CallCodeObject(Handle<Code> code,
306 RelocInfo::Mode rmode,
307 int dropped_args) {
308 int spilled_args = 0;
309 switch (code->kind()) {
310 case Code::CALL_IC:
311 spilled_args = dropped_args + 1;
312 break;
313 case Code::FUNCTION:
314 spilled_args = dropped_args + 1;
315 break;
316 case Code::KEYED_LOAD_IC:
317 ASSERT(dropped_args == 0);
318 spilled_args = 2;
319 break;
320 default:
321 // The other types of code objects are called with values
322 // in specific registers, and are handled in functions with
323 // a different signature.
324 UNREACHABLE();
325 break;
326 }
327 PrepareForCall(spilled_args, dropped_args);
328 return RawCallCodeObject(code, rmode);
329 }
330
331
332 Result VirtualFrame::CallCodeObject(Handle<Code> code,
333 RelocInfo::Mode rmode,
334 Result* arg,
335 int dropped_args) {
336 int spilled_args = 0;
337 switch (code->kind()) {
338 case Code::LOAD_IC:
339 ASSERT(arg->reg().is(r2));
340 ASSERT(dropped_args == 0);
341 spilled_args = 1;
342 break;
343 case Code::KEYED_STORE_IC:
344 ASSERT(arg->reg().is(r0));
345 ASSERT(dropped_args == 0);
346 spilled_args = 2;
347 break;
348 default:
349 // No other types of code objects are called with values
350 // in exactly one register.
351 UNREACHABLE();
352 break;
353 }
354 PrepareForCall(spilled_args, dropped_args);
355 arg->Unuse();
356 return RawCallCodeObject(code, rmode);
357 }
358
359
360 Result VirtualFrame::CallCodeObject(Handle<Code> code,
361 RelocInfo::Mode rmode,
362 Result* arg0,
363 Result* arg1,
364 int dropped_args) {
365 int spilled_args = 1;
366 switch (code->kind()) {
367 case Code::STORE_IC:
368 ASSERT(arg0->reg().is(r0));
369 ASSERT(arg1->reg().is(r2));
370 ASSERT(dropped_args == 0);
371 spilled_args = 1;
372 break;
373 case Code::BUILTIN:
374 ASSERT(*code == Builtins::builtin(Builtins::JSConstructCall));
375 ASSERT(arg0->reg().is(r0));
376 ASSERT(arg1->reg().is(r1));
377 spilled_args = dropped_args + 1;
378 break;
379 default:
380 // No other types of code objects are called with values
381 // in exactly two registers.
382 UNREACHABLE();
383 break;
384 }
385 PrepareForCall(spilled_args, dropped_args);
386 arg0->Unuse();
387 arg1->Unuse();
388 return RawCallCodeObject(code, rmode);
389 }
390
391
392 void VirtualFrame::Drop(int count) {
393 ASSERT(height() >= count);
394 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_;
395
396 // Emit code to lower the stack pointer if necessary.
397 if (num_virtual_elements < count) {
398 int num_dropped = count - num_virtual_elements;
399 stack_pointer_ -= num_dropped;
400 __ add(sp, sp, Operand(num_dropped * kPointerSize));
401 }
402
403 // Discard elements from the virtual frame and free any registers.
404 for (int i = 0; i < count; i++) {
405 FrameElement dropped = elements_.RemoveLast();
406 if (dropped.is_register()) {
407 Unuse(dropped.reg());
408 }
409 }
410 }
411
412
413 Result VirtualFrame::Pop() {
414 UNIMPLEMENTED();
415 Result invalid(cgen_);
416 return invalid;
417 }
418
419
420 void VirtualFrame::EmitPop(Register reg) {
421 ASSERT(stack_pointer_ == elements_.length() - 1);
422 stack_pointer_--;
423 elements_.RemoveLast();
424 __ pop(reg);
425 }
426
427
428 void VirtualFrame::EmitPush(Register reg) {
429 ASSERT(stack_pointer_ == elements_.length() - 1);
430 elements_.Add(FrameElement::MemoryElement());
431 stack_pointer_++;
432 __ push(reg);
433 }
434
435
436 #undef __
437
438 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/virtual-frame-arm.h ('k') | src/assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698