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

Side by Side Diff: src/register-allocator-ia32.cc

Issue 15079: Experimental: this is a substantial change to allow the virtual frame... (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
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 21 matching lines...) Expand all
32 32
33 namespace v8 { namespace internal { 33 namespace v8 { namespace internal {
34 34
35 // ------------------------------------------------------------------------- 35 // -------------------------------------------------------------------------
36 // Result implementation. 36 // Result implementation.
37 37
38 Result::Result(Register reg, CodeGenerator* cgen) 38 Result::Result(Register reg, CodeGenerator* cgen)
39 : type_(REGISTER), 39 : type_(REGISTER),
40 cgen_(cgen) { 40 cgen_(cgen) {
41 data_.reg_ = reg; 41 data_.reg_ = reg;
42 ASSERT(!reg.is(no_reg)); 42 ASSERT(reg.is_valid());
43 cgen_->allocator()->Use(reg); 43 cgen_->allocator()->Use(reg);
44 } 44 }
45 45
46 46
47 void Result::CopyTo(Result* destination) const { 47 void Result::CopyTo(Result* destination) const {
48 destination->type_ = type(); 48 destination->type_ = type();
49 destination->cgen_ = cgen_; 49 destination->cgen_ = cgen_;
50 50
51 if (is_register()) { 51 if (is_register()) {
52 destination->data_.reg_ = reg(); 52 destination->data_.reg_ = reg();
(...skipping 14 matching lines...) Expand all
67 } 67 }
68 68
69 69
70 void Result::ToRegister() { 70 void Result::ToRegister() {
71 ASSERT(is_valid()); 71 ASSERT(is_valid());
72 if (is_constant()) { 72 if (is_constant()) {
73 Result fresh = cgen_->allocator()->Allocate(); 73 Result fresh = cgen_->allocator()->Allocate();
74 ASSERT(fresh.is_valid()); 74 ASSERT(fresh.is_valid());
75 cgen_->masm()->Set(fresh.reg(), Immediate(handle())); 75 cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
76 // This result becomes a copy of the fresh one. 76 // This result becomes a copy of the fresh one.
77 cgen_->allocator()->Use(fresh.reg()); 77 *this = fresh;
78 type_ = REGISTER;
79 data_.reg_ = fresh.reg();
80 } 78 }
81 ASSERT(is_register()); 79 ASSERT(is_register());
82 } 80 }
83 81
84 82
83 void Result::ToRegister(Register target) {
84 ASSERT(is_valid());
85 if (!is_register() || !reg().is(target)) {
86 Result fresh = cgen_->allocator()->Allocate(target);
87 ASSERT(fresh.is_valid());
88 if (is_register()) {
89 cgen_->masm()->mov(fresh.reg(), reg());
90 } else {
91 ASSERT(is_constant());
92 cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
93 }
94 *this = fresh;
95 }
William Hesse 2008/12/22 13:55:21 I think we are missing the case where this.reg() i
Kevin Millikin (Chromium) 2008/12/22 14:40:00 Yes, according to the comment in the header we do.
96 ASSERT(is_register());
97 ASSERT(reg().is(target));
98 }
99
100
85 // ------------------------------------------------------------------------- 101 // -------------------------------------------------------------------------
86 // RegisterAllocator implementation. 102 // RegisterAllocator implementation.
87 103
88 void RegisterAllocator::Initialize() { 104 void RegisterAllocator::Initialize() {
89 registers_.Reset(); 105 registers_.Reset();
90 Use(esp); 106 Use(esp);
91 Use(ebp); 107 Use(ebp);
92 Use(esi); 108 Use(esi);
93 Use(edi); 109 Use(edi);
William Hesse 2008/12/22 13:55:21 Aren't we going to need to unuse edi before the Va
Kevin Millikin (Chromium) 2008/12/22 14:40:00 We can't jump before Enter is called on the frame.
94 } 110 }
95 111
96 112
97 Result RegisterAllocator::AllocateWithoutSpilling() { 113 Result RegisterAllocator::AllocateWithoutSpilling() {
98 // Return the first free register, if any. 114 // Return the first free register, if any.
99 for (int i = 0; i < num_registers(); i++) { 115 for (int i = 0; i < num_registers(); i++) {
100 if (!is_used(i)) { 116 if (!is_used(i)) {
101 Register free_reg = { i }; 117 Register free_reg = { i };
102 return Result(free_reg, cgen_); 118 return Result(free_reg, cgen_);
103 } 119 }
104 } 120 }
105 return Result(cgen_); 121 return Result(cgen_);
106 } 122 }
107 123
108 124
109 Result RegisterAllocator::Allocate() { 125 Result RegisterAllocator::Allocate() {
110 Result result = AllocateWithoutSpilling(); 126 Result result = AllocateWithoutSpilling();
111 if (!result.is_valid()) { 127 if (!result.is_valid()) {
112 // Ask the current frame to spill a register. 128 // Ask the current frame to spill a register.
113 ASSERT(cgen_->frame() != NULL); 129 ASSERT(cgen_->frame() != NULL);
114 Register free_reg = cgen_->frame()->SpillAnyRegister(); 130 Register free_reg = cgen_->frame()->SpillAnyRegister();
115 if (free_reg.is_valid()) { 131 if (free_reg.is_valid()) {
116 ASSERT(!is_used(free_reg.code())); 132 ASSERT(!is_used(free_reg));
117 return Result(free_reg, cgen_); 133 return Result(free_reg, cgen_);
118 } 134 }
119 } 135 }
120 return result; 136 return result;
121 } 137 }
122 138
123 139
140 Result RegisterAllocator::Allocate(Register target) {
141 // If the target is not referenced, it can simply be allocated.
142 if (!is_used(target)) {
143 return Result(target, cgen_);
144 }
145 // If the target is only referenced in the frame, it can be spilled and
146 // then allocated.
147 ASSERT(cgen_->frame() != NULL);
148 if (count(target) == cgen_->frame()->register_count(target)) {
149 cgen_->frame()->Spill(target);
150 ASSERT(!is_used(target));
151 return Result(target, cgen_);
152 }
153 // Otherwise (if it's referenced outside the frame) we cannot allocate it.
154 return Result(cgen_);
155 }
156
157
124 } } // namespace v8::internal 158 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698