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

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

Issue 13246: Experimental: more code generator changes.... (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
« no previous file with comments | « 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 26 matching lines...) Expand all
37 37
38 38
39 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
40 // Result implementation. 40 // Result implementation.
41 41
42 42
43 Result::Result(Register reg, CodeGenerator* cgen) 43 Result::Result(Register reg, CodeGenerator* cgen)
44 : type_(REGISTER), 44 : type_(REGISTER),
45 cgen_(cgen) { 45 cgen_(cgen) {
46 data_.reg_ = reg; 46 data_.reg_ = reg;
47 ASSERT(!reg().is(no_reg)); 47 ASSERT(!reg.is(no_reg));
48 cgen_->allocator()->Use(reg); 48 cgen_->allocator()->Use(reg);
49 } 49 }
50 50
51 51
52 void Result::Unuse() { 52 void Result::Unuse() {
53 ASSERT(!reg().is(no_reg)); 53 ASSERT(!reg().is(no_reg));
54 cgen_->allocator()->Unuse(reg()); 54 cgen_->allocator()->Unuse(reg());
55 data_.reg_ = no_reg; 55 data_.reg_ = no_reg;
56 } 56 }
57 57
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 233
234 // Clear the dirty bits for the range of elements in [begin, end). 234 // Clear the dirty bits for the range of elements in [begin, end).
235 void VirtualFrame::SyncRange(int begin, int end) { 235 void VirtualFrame::SyncRange(int begin, int end) {
236 ASSERT(begin >= 0); 236 ASSERT(begin >= 0);
237 ASSERT(end <= elements_.length()); 237 ASSERT(end <= elements_.length());
238 for (int i = begin; i < end; i++) { 238 for (int i = begin; i < end; i++) {
239 SyncElementAt(i); 239 SyncElementAt(i);
240 } 240 }
241 } 241 }
242 242
243
243 // Make the type of all elements be MEMORY. 244 // Make the type of all elements be MEMORY.
244 void VirtualFrame::SpillAll() { 245 void VirtualFrame::SpillAll() {
245 for (int i = 0; i < elements_.length(); i++) { 246 for (int i = 0; i < elements_.length(); i++) {
246 SpillElementAt(i); 247 SpillElementAt(i);
247 } 248 }
248 } 249 }
249 250
250 251
251 void VirtualFrame::PrepareForCall(int frame_arg_count) { 252 void VirtualFrame::PrepareForCall(int frame_arg_count) {
252 ASSERT(height() >= frame_arg_count); 253 ASSERT(height() >= frame_arg_count);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 for (int i = 0; i < elements_.length(); i++) { 290 for (int i = 0; i < elements_.length(); i++) {
290 if (!elements_[i].is_memory() && !elements_[i].is_register()) { 291 if (!elements_[i].is_memory() && !elements_[i].is_register()) {
291 return false; 292 return false;
292 } 293 }
293 } 294 }
294 295
295 return true; 296 return true;
296 } 297 }
297 298
298 299
300 bool VirtualFrame::RequiresMergeCode() {
301 // A frame requires merge code to be generated in the event that
302 // there are duplicated non-synched registers or else elements not
303 // in a (memory or register) location in the frame. We look for
304 // non-synced non-location elements and count occurrences of
305 // non-synced registers.
306 RegisterFile non_synced_regs;
307 for (int i = 0; i < elements_.length(); i++) {
308 FrameElement element = elements_[i];
309 if (!element.is_synced()) {
310 if (element.is_register()) {
311 non_synced_regs.Use(elements_[i].reg());
312 } else if (!element.is_memory()) {
313 // Not memory or register and not synced.
314 return true;
315 }
316 }
317 }
318
319 for (int i = 0; i < RegisterFile::kNumRegisters; i++) {
320 if (non_synced_regs.count(i) > 1) {
321 return true;
322 }
323 }
324
325 return false;
326 }
327
328
299 void VirtualFrame::MakeMergable() { 329 void VirtualFrame::MakeMergable() {
300 Comment cmnt(masm_, "[ Make frame mergable"); 330 Comment cmnt(masm_, "[ Make frame mergable");
301 // Remove constants from the frame and ensure that no registers are 331 // Remove constants from the frame and ensure that no registers are
302 // multiply referenced within the frame. Allocate elements to their 332 // multiply referenced within the frame. Allocate elements to their
303 // new locations from the top down so that the topmost elements have 333 // new locations from the top down so that the topmost elements have
304 // a chance to be in registers, then fill them into memory from the 334 // a chance to be in registers, then fill them into memory from the
305 // bottom up. (NB: Currently when spilling registers that are 335 // bottom up. (NB: Currently when spilling registers that are
306 // multiply referenced, it is the lowermost occurrence that gets to 336 // multiply referenced, it is the lowermost occurrence that gets to
307 // stay in the register.) 337 // stay in the register.)
308 FrameElement* new_elements = new FrameElement[elements_.length()]; 338 FrameElement* new_elements = new FrameElement[elements_.length()];
309 FrameElement memory_element; 339 FrameElement memory_element;
310 for (int i = elements_.length() - 1; i >= 0; i--) { 340 for (int i = elements_.length() - 1; i >= 0; i--) {
311 FrameElement element = elements_[i]; 341 FrameElement element = elements_[i];
312 if (element.is_constant() || 342 if (element.is_constant() ||
313 (element.is_register() && 343 (element.is_register() &&
314 frame_registers_.count(element.reg().code()) > 1)) { 344 frame_registers_.count(element.reg().code()) > 1)) {
315 // A simple strategy is to locate these elements in memory if they are 345 // A simple strategy is to locate these elements in memory if they are
316 // synced (avoiding a spill right now) and otherwise to prefer a 346 // synced (avoiding a spill right now) and otherwise to prefer a
317 // register for them. 347 // register for them.
318 if (element.is_synced()) { 348 if (element.is_synced()) {
319 new_elements[i] = memory_element; 349 new_elements[i] = memory_element;
320 } else { 350 } else {
321 // This code path is currently not triggered. UNIMPLEMENTED is
322 // temporarily used to trap when it becomes active so we can test
323 // it.
324 UNIMPLEMENTED();
325 Register reg = cgen_->allocator()->AllocateWithoutSpilling(); 351 Register reg = cgen_->allocator()->AllocateWithoutSpilling();
326 if (reg.is(no_reg)) { 352 if (reg.is(no_reg)) {
327 new_elements[i] = memory_element; 353 new_elements[i] = memory_element;
328 } else { 354 } else {
329 FrameElement register_element(reg, FrameElement::NOT_SYNCED); 355 FrameElement register_element(reg, FrameElement::NOT_SYNCED);
330 new_elements[i] = register_element; 356 new_elements[i] = register_element;
331 } 357 }
332 } 358 }
333 359
334 // We have not moved register references, but record that we will so 360 // We have not moved register references, but record that we will so
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 ASSERT(!elements_[j].is_memory()); 451 ASSERT(!elements_[j].is_memory());
426 } 452 }
427 #endif 453 #endif
428 stack_pointer_ = i + 1; 454 stack_pointer_ = i + 1;
429 __ add(Operand(esp), 455 __ add(Operand(esp),
430 Immediate((stack_pointer_ - i) * kPointerSize)); 456 Immediate((stack_pointer_ - i) * kPointerSize));
431 } 457 }
432 stack_pointer_--; 458 stack_pointer_--;
433 __ pop(target.reg()); 459 __ pop(target.reg());
434 } 460 }
435 Use(target.reg()); 461 } else {
436 } else if (source.is_constant()) { 462 // Source is constant.
437 // Not yet implemented. When done, code in common with the 463 __ Set(target.reg(), Immediate(source.handle()));
438 // memory-to-register just above case can be factored out.
439 UNIMPLEMENTED();
440 } 464 }
465 Use(target.reg());
441 elements_[i] = target; 466 elements_[i] = target;
442 } 467 }
443 } 468 }
444 469
470 // At this point, the frames should be identical.
445 ASSERT(stack_pointer_ == expected->stack_pointer_); 471 ASSERT(stack_pointer_ == expected->stack_pointer_);
472 #ifdef DEBUG
473 for (int i = 0; i < elements_.length(); i++) {
474 FrameElement expect = expected->elements_[i];
475 if (expect.is_memory()) {
476 ASSERT(elements_[i].is_memory());
477 ASSERT(elements_[i].is_synced() && expect.is_synced());
478 } else if (expect.is_register()) {
479 ASSERT(elements_[i].is_register());
480 ASSERT(elements_[i].reg().is(expect.reg()));
481 ASSERT(elements_[i].is_synced() == expect.is_synced());
482 } else {
483 ASSERT(expect.is_constant());
484 ASSERT(elements_[i].is_constant());
485 ASSERT(elements_[i].handle().location() ==
486 expect.handle().location());
487 ASSERT(elements_[i].is_synced() == expect.is_synced());
488 }
489 }
490 #endif
491 }
492
493
494 void VirtualFrame::DetachFromCodeGenerator() {
495 // Tell the global register allocator that it is free to reallocate all
496 // register references contained in this frame. The frame elements remain
497 // register references, so the frame-internal reference count is not
498 // decremented.
499 for (int i = 0; i < elements_.length(); i++) {
500 if (elements_[i].is_register()) {
501 cgen_->allocator()->Unuse(elements_[i].reg());
502 }
503 }
504 }
505
506
507 void VirtualFrame::AttachToCodeGenerator() {
508 // Tell the global register allocator that the frame-internal register
509 // references are live again.
510 for (int i = 0; i < elements_.length(); i++) {
511 if (elements_[i].is_register()) {
512 cgen_->allocator()->Use(elements_[i].reg());
513 }
514 }
446 } 515 }
447 516
448 517
449 void VirtualFrame::Enter() { 518 void VirtualFrame::Enter() {
450 // Registers live on entry: esp, ebp, esi, edi. 519 // Registers live on entry: esp, ebp, esi, edi.
451 Comment cmnt(masm_, "[ Enter JS frame"); 520 Comment cmnt(masm_, "[ Enter JS frame");
452 EmitPush(ebp); 521 EmitPush(ebp);
453 522
454 frame_pointer_ = stack_pointer_; 523 frame_pointer_ = stack_pointer_;
455 __ mov(ebp, Operand(esp)); 524 __ mov(ebp, Operand(esp));
456 525
457 // Store the context and the function in the frame. 526 // Store the context in the frame. The context is kept in esi, so the
458 Push(esi); 527 // register reference is not owned by the frame (ie, the frame is not free
459 // The frame owns the register reference now. 528 // to spill it). This is implemented by making the in-frame value be
460 cgen_->allocator()->Unuse(esi); 529 // memory.
530 EmitPush(esi);
461 531
532 // Store the function in the frame. The frame owns the register reference
533 // now (ie, it can keep it in edi or spill it later).
462 Push(edi); 534 Push(edi);
463 cgen_->allocator()->Unuse(edi); 535 cgen_->allocator()->Unuse(edi);
464 } 536 }
465 537
466 538
467 void VirtualFrame::Exit() { 539 void VirtualFrame::Exit() {
468 Comment cmnt(masm_, "[ Exit JS frame"); 540 Comment cmnt(masm_, "[ Exit JS frame");
469 // Record the location of the JS exit code for patching when setting 541 // Record the location of the JS exit code for patching when setting
470 // break point. 542 // break point.
471 __ RecordJSReturn(); 543 __ RecordJSReturn();
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 return false; 789 return false;
718 } 790 }
719 } 791 }
720 return true; 792 return true;
721 } 793 }
722 #endif 794 #endif
723 795
724 #undef __ 796 #undef __
725 797
726 } } // namespace v8::internal 798 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698