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

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

Issue 10993: Begin using the virtual frame for assignment statements of the form:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years 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 | Annotate | Revision Log
« src/virtual-frame-ia32.h ('K') | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 153 }
154 154
155 155
156 // Spill any register if possible, making its reference count zero. 156 // Spill any register if possible, making its reference count zero.
157 Register VirtualFrame::SpillAnyRegister() { 157 Register VirtualFrame::SpillAnyRegister() {
158 // Find the leftmost (ordered by register code), least 158 // Find the leftmost (ordered by register code), least
159 // internally-referenced register whose internal reference count matches 159 // internally-referenced register whose internal reference count matches
160 // its external reference count (so that spilling it from the frame frees 160 // its external reference count (so that spilling it from the frame frees
161 // it for use). 161 // it for use).
162 int min_count = kMaxInt; 162 int min_count = kMaxInt;
163 int best_register_code = no_reg.code(); 163 int best_register_code = no_reg.code_;
164 164
165 for (int i = 0; i < RegisterFile::kNumRegisters; i++) { 165 for (int i = 0; i < RegisterFile::kNumRegisters; i++) {
166 int count = frame_registers_.count(i); 166 int count = frame_registers_.count(i);
167 if (count < min_count && count == cgen_->allocator()->count(i)) { 167 if (count < min_count && count == cgen_->allocator()->count(i)) {
168 min_count = count; 168 min_count = count;
169 best_register_code = i; 169 best_register_code = i;
170 } 170 }
171 } 171 }
172 172
173 if (best_register_code != no_reg.code()) { 173 if (best_register_code != no_reg.code_) {
174 // Spill all occurrences of the register. There are min_count 174 // Spill all occurrences of the register. There are min_count
175 // occurrences, stop when we've spilled them all to avoid syncing 175 // occurrences, stop when we've spilled them all to avoid syncing
176 // elements unnecessarily. 176 // elements unnecessarily.
177 int i = 0; 177 int i = 0;
178 while (min_count > 0) { 178 while (min_count > 0) {
179 ASSERT(i < elements_.length()); 179 ASSERT(i < elements_.length());
180 if (elements_[i].is_register() && 180 if (elements_[i].is_register() &&
181 elements_[i].reg().code() == best_register_code) { 181 elements_[i].reg().code() == best_register_code) {
182 // Found an instance of the best_register being used in the frame. 182 // Found an instance of the best_register being used in the frame.
183 // Spill it. 183 // Spill it.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 for (int i = 0; i < count; i++) { 340 for (int i = 0; i < count; i++) {
341 elements_.Add(initial_value); 341 elements_.Add(initial_value);
342 stack_pointer_++; 342 stack_pointer_++;
343 __ push(tmp); 343 __ push(tmp);
344 } 344 }
345 cgen_->allocator()->Unuse(tmp); 345 cgen_->allocator()->Unuse(tmp);
346 } 346 }
347 } 347 }
348 348
349 349
350 void VirtualFrame::StoreToFrameSlotAt(int index) {
William Hesse 2008/11/28 10:32:45 So this changelist enables the register and memory
Kevin Millikin (Chromium) 2008/11/28 12:19:08 It is expected to correctly handle constants.
351 // Store the value on top of the frame to the virtual frame slot at a
352 // given index. The value on top of the frame is left in place.
353 ASSERT(index < elements_.length());
354 FrameElement top = elements_[elements_.length() - 1];
355
356 // The virtual frame slot is now of the same type and has the same value
357 // as the frame top.
358 elements_[index] = top;
William Hesse 2008/11/28 10:32:45 Don't we need to unuse elements_[index] if it is a
Kevin Millikin (Chromium) 2008/11/28 12:19:08 Yes. Good catch.
359
360 if (top.is_memory()) {
361 // Emit code to store memory values into the required frame slot.
362 Register tmp = cgen_->allocator()->Allocate();
363 ASSERT(!tmp.is(no_reg));
William Hesse 2008/11/28 10:32:45 Will we actually need error handling code in the f
Kevin Millikin (Chromium) 2008/11/28 12:19:08 We don't have a good way to handle that yet. I'm
364 __ mov(tmp, Top());
365 __ mov(Operand(ebp, fp_relative(index)), tmp);
366 cgen_->allocator()->Unuse(tmp);
367 } else {
368 // We haven't actually written the value to memory.
369 elements_[index].clear_sync();
370
371 if (top.is_register()) {
372 // Establish another frame-internal reference to the register.
373 Use(top.reg());
374 }
375 }
376 }
377
378
350 void VirtualFrame::PushTryHandler(HandlerType type) { 379 void VirtualFrame::PushTryHandler(HandlerType type) {
351 // Grow the expression stack by handler size less two (the return address 380 // Grow the expression stack by handler size less two (the return address
352 // is already pushed by a call instruction, and PushTryHandler from the 381 // is already pushed by a call instruction, and PushTryHandler from the
353 // macro assembler will leave the top of stack in the eax register to be 382 // macro assembler will leave the top of stack in the eax register to be
354 // pushed separately). 383 // pushed separately).
355 Adjust(kHandlerSize - 2); 384 Adjust(kHandlerSize - 2);
356 __ PushTryHandler(IN_JAVASCRIPT, type); 385 __ PushTryHandler(IN_JAVASCRIPT, type);
357 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS 386 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS
358 EmitPush(eax); 387 EmitPush(eax);
359 } 388 }
(...skipping 28 matching lines...) Expand all
388 void VirtualFrame::CallCodeObject(Handle<Code> code, 417 void VirtualFrame::CallCodeObject(Handle<Code> code,
389 RelocInfo::Mode rmode, 418 RelocInfo::Mode rmode,
390 int frame_arg_count) { 419 int frame_arg_count) {
391 PrepareForCall(frame_arg_count); 420 PrepareForCall(frame_arg_count);
392 __ call(code, rmode); 421 __ call(code, rmode);
393 } 422 }
394 423
395 424
396 void VirtualFrame::Drop(int count) { 425 void VirtualFrame::Drop(int count) {
397 ASSERT(height() >= count); 426 ASSERT(height() >= count);
427 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_;
398 428
399 // Discard elements above the stack pointer. 429 // Emit code to lower the stack pointer if necessary.
400 while (count > 0 && stack_pointer_ < elements_.length() - 1) { 430 if (num_virtual_elements < count) {
401 FrameElement last = elements_.RemoveLast(); 431 int num_dropped = count - num_virtual_elements;
402 if (last.is_register()) { 432 stack_pointer_ -= num_dropped;
403 Unuse(last.reg()); 433 __ add(Operand(esp), Immediate(num_dropped * kPointerSize));
404 }
405 } 434 }
406 435
407 // Discard the rest of the elements and lower the stack pointer. 436 // Discard elements from the virtual frame and free any registers.
408 Forget(count); 437 for (int i = 0; i < count; i++) {
409 if (count > 0) { 438 FrameElement dropped = elements_.RemoveLast();
410 __ add(Operand(esp), Immediate(count * kPointerSize)); 439 if (dropped.is_register()) {
440 Unuse(dropped.reg());
441 }
411 } 442 }
412 } 443 }
413 444
414 445
415 void VirtualFrame::Drop() { Drop(1); } 446 void VirtualFrame::Drop() { Drop(1); }
416 447
417 448
418 void VirtualFrame::EmitPop(Register reg) { 449 void VirtualFrame::EmitPop(Register reg) {
419 ASSERT(stack_pointer_ == elements_.length() - 1); 450 ASSERT(stack_pointer_ == elements_.length() - 1);
420 stack_pointer_--; 451 stack_pointer_--;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 elements_.Add(register_element); 493 elements_.Add(register_element);
463 } 494 }
464 495
465 496
466 void VirtualFrame::Push(Handle<Object> value) { 497 void VirtualFrame::Push(Handle<Object> value) {
467 FrameElement constant_element(value, FrameElement::NOT_SYNCED); 498 FrameElement constant_element(value, FrameElement::NOT_SYNCED);
468 elements_.Add(constant_element); 499 elements_.Add(constant_element);
469 } 500 }
470 501
471 502
503 #ifdef DEBUG
504 bool VirtualFrame::IsSpilled() {
505 for (int i = 0; i < elements_.length(); i++) {
506 if (!elements_[i].is_memory()) {
507 return false;
508 }
509 }
510 return true;
511 }
512 #endif
513
472 #undef __ 514 #undef __
473 515
474 } } // namespace v8::internal 516 } } // namespace v8::internal
OLDNEW
« src/virtual-frame-ia32.h ('K') | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698