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

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

Issue 11472: Experimental: initial simple support for registers in the virtual... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years, 1 month 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
« v8/src/virtual-frame-ia32.h ('K') | « v8/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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 ASSERT(stack_pointer_ == elements_.length() - 1); 92 ASSERT(stack_pointer_ == elements_.length() - 1);
93 ASSERT(elements_.length() >= count); 93 ASSERT(elements_.length() >= count);
94 94
95 stack_pointer_ -= count; 95 stack_pointer_ -= count;
96 for (int i = 0; i < count; i++) { 96 for (int i = 0; i < count; i++) {
97 elements_.RemoveLast(); 97 elements_.RemoveLast();
98 } 98 }
99 } 99 }
100 100
101 101
102 void VirtualFrame::SyncElementAt(int index) {
iposva 2008/11/20 05:49:35 Comment please.
103 FrameElement element = elements_[index];
104
105 if (index <= stack_pointer_ && element.is_dirty()) {
106 // Write elements below the stack pointer to their (already allocated)
107 // actual frame location.
108 if (element.is_constant()) {
109 __ Set(Operand(ebp, fp_relative(index)), Immediate(element.handle()));
110 } else {
111 ASSERT(element.is_register());
112 __ mov(Operand(ebp, fp_relative(index)), element.reg());
113 }
114
115 } else if (index > stack_pointer_) {
116 // Push elements above the stack pointer to allocate space and sync
117 // them. Space should have already been allocated in the actual frame
118 // for all the elements below this one.
119 ASSERT(index == stack_pointer_ - 1);
iposva 2008/11/20 05:49:35 I would expect that elements above the stack point
Kevin Millikin (Chromium) 2008/11/20 08:28:03 Yes: elements above the stack pointer are always d
120 if (element.is_constant()) {
121 stack_pointer_++;
122 __ push(Immediate(element.handle()));
123 } else {
124 ASSERT(element.is_register());
125 stack_pointer_++;
iposva 2008/11/20 05:49:35 The stack_pointer_ update should be factored out o
Kevin Millikin (Chromium) 2008/11/20 08:28:03 OK.
126 __ push(element.reg());
127 }
128 }
129 }
130
131
132 void VirtualFrame::SpillElementAt(int index) {
iposva 2008/11/20 05:49:35 Comment please. Especially since the distinction
133 SyncElementAt(index);
134 // The element is now in memory.
135 elements_[index] = FrameElement();
136 }
137
138
102 void VirtualFrame::SpillAll() { 139 void VirtualFrame::SpillAll() {
103 int i = 0; 140 for (int i = 0; i < elements_.length(); i++) {
104 141 SpillElementAt(i);
105 // Spill dirty constants below the stack pointer.
106 for (; i <= stack_pointer_; i++) {
107 if (elements_[i].type() == FrameElement::CONSTANT &&
108 elements_[i].is_dirty()) {
109 __ mov(Operand(ebp, fp_relative(i)), Immediate(elements_[i].handle()));
110 elements_[i] = FrameElement(); // The element is now in memory.
111 }
112 }
113
114 // Spill all constants above the stack pointer.
115 for (; i < elements_.length(); i++) {
116 ASSERT(elements_[i].type() == FrameElement::CONSTANT);
117 ASSERT(elements_[i].is_dirty());
118 stack_pointer_++;
119 __ push(Immediate(elements_[i].handle()));
120 elements_[i] = FrameElement(); // The element is now in memory.
121 } 142 }
122 } 143 }
123 144
124 145
125 void VirtualFrame::PrepareForCall(int frame_arg_count) { 146 void VirtualFrame::PrepareForCall(int frame_arg_count) {
126 ASSERT(height() >= frame_arg_count); 147 ASSERT(height() >= frame_arg_count);
127 148
128 // The only non-memory elements of the frame are constants. Push all of 149 // Below the stack pointer, spill all registers.
129 // them above the stack pointer to allocate space for them and to ensure 150 for (int i = 0; i <= stack_pointer_; i++) {
130 // the arguments are flushed to memory. 151 if (elements_[i].is_register()) {
131 for (int i = stack_pointer_ + 1; i < elements_.length(); i++) { 152 SpillElementAt(i);
132 ASSERT(elements_[i].type() == FrameElement::CONSTANT); 153 }
133 ASSERT(elements_[i].is_dirty());
134 stack_pointer_++;
135 elements_[i].clear_dirty();
136 __ push(Immediate(elements_[i].handle()));
137 } 154 }
138 155
139 // Forget the ones that will be popped by the call. 156 // Above the stack pointer, spill registers and sync everything else (ie,
157 // constants).
158 for (int i = stack_pointer_ + 1; i < elements_.length(); i++) {
159 if (elements_[i].is_register()) {
160 SpillElementAt(i);
161 } else {
162 SyncElementAt(i);
163 }
164 }
165
166 // Forget the frame elements that will be popped by the call.
140 Forget(frame_arg_count); 167 Forget(frame_arg_count);
141 } 168 }
142 169
143 170
144 void VirtualFrame::EnsureMergable() { 171 void VirtualFrame::EnsureMergable() {
145 // We cannot merge to a frame that has constants as elements, because an 172 // We cannot merge to a frame that has constants as elements, because an
146 // arbitrary frame may not have constants in those locations. 173 // arbitrary frame might not have constants in those locations.
174 //
175 // We cannot merge to a frame that has registers as elements because we
176 // haven't implemented merging for such frames yet.
147 SpillAll(); 177 SpillAll();
148 } 178 }
149 179
150 180
151 void VirtualFrame::MergeTo(VirtualFrame* expected) { 181 void VirtualFrame::MergeTo(VirtualFrame* expected) {
152 ASSERT(masm_ == expected->masm_); 182 ASSERT(masm_ == expected->masm_);
153 ASSERT(elements_.length() == expected->elements_.length()); 183 ASSERT(elements_.length() == expected->elements_.length());
154 ASSERT(parameter_count_ == expected->parameter_count_); 184 ASSERT(parameter_count_ == expected->parameter_count_);
155 ASSERT(local_count_ == expected->local_count_); 185 ASSERT(local_count_ == expected->local_count_);
156 ASSERT(frame_pointer_ == expected->frame_pointer_); 186 ASSERT(frame_pointer_ == expected->frame_pointer_);
157 187
158 // The expected frame is one we can merge to (ie, currently that means 188 // Mergable frames do not have constants and they do not (currently) have
159 // that all elements are in memory). The only thing we need to do to 189 // registers. They are always fully spilled, so the only thing needed to
160 // merge is make this one mergable too. 190 // make this frame match the expected one is to spill everything.
191 //
192 // TODO(): Implement a non-stupid way of merging frames.
161 SpillAll(); 193 SpillAll();
162 194
163 ASSERT(stack_pointer_ == expected->stack_pointer_); 195 ASSERT(stack_pointer_ == expected->stack_pointer_);
164 } 196 }
165 197
166 198
167 void VirtualFrame::Enter() { 199 void VirtualFrame::Enter() {
168 Comment cmnt(masm_, "[ Enter JS frame"); 200 Comment cmnt(masm_, "[ Enter JS frame");
169 EmitPush(ebp); 201 EmitPush(ebp);
170 202
171 frame_pointer_ = stack_pointer_; 203 frame_pointer_ = stack_pointer_;
172 __ mov(ebp, Operand(esp)); 204 __ mov(ebp, Operand(esp));
173 205
174 // Store the context and the function in the frame. 206 // Store the context and the function in the frame.
175 EmitPush(esi); 207 FrameElement context(esi);
176 EmitPush(edi); 208 context.clear_dirty();
209 elements_.Add(context);
210 stack_pointer_++;
211 __ push(esi);
212
213 FrameElement function(edi);
214 function.clear_dirty();
215 elements_.Add(function);
216 stack_pointer_++;
217 __ push(edi);
177 218
178 // Clear the function slot when generating debug code. 219 // Clear the function slot when generating debug code.
179 if (FLAG_debug_code) { 220 if (FLAG_debug_code) {
221 SpillElementAt(stack_pointer_);
180 __ Set(edi, Immediate(reinterpret_cast<int>(kZapValue))); 222 __ Set(edi, Immediate(reinterpret_cast<int>(kZapValue)));
181 } 223 }
182 } 224 }
183 225
184 226
185 void VirtualFrame::Exit() { 227 void VirtualFrame::Exit() {
186 Comment cmnt(masm_, "[ Exit JS frame"); 228 Comment cmnt(masm_, "[ Exit JS frame");
187 // Record the location of the JS exit code for patching when setting 229 // Record the location of the JS exit code for patching when setting
188 // break point. 230 // break point.
189 __ RecordJSReturn(); 231 __ RecordJSReturn();
190 232
191 // Avoid using the leave instruction here, because it is too 233 // Avoid using the leave instruction here, because it is too
192 // short. We need the return sequence to be a least the size of a 234 // short. We need the return sequence to be a least the size of a
193 // call instruction to support patching the exit code in the 235 // call instruction to support patching the exit code in the
194 // debugger. See VisitReturnStatement for the full return sequence. 236 // debugger. See VisitReturnStatement for the full return sequence.
195 __ mov(esp, Operand(ebp)); 237 __ mov(esp, Operand(ebp));
196 stack_pointer_ = frame_pointer_; 238 stack_pointer_ = frame_pointer_;
197 for (int i = elements_.length() - 1; i > stack_pointer_; i--) { 239 for (int i = elements_.length() - 1; i > stack_pointer_; i--) {
198 elements_.RemoveLast(); 240 elements_.RemoveLast();
199 } 241 }
200 242
201 frame_pointer_ = kIllegalIndex; 243 frame_pointer_ = kIllegalIndex;
202 EmitPop(ebp); 244 EmitPop(ebp);
203 } 245 }
204 246
205 247
206 void VirtualFrame::AllocateStackSlots(int count) { 248 void VirtualFrame::AllocateStackSlots(int count) {
207 ASSERT(height() == 0); 249 ASSERT(height() == 0);
208 local_count_ = count; 250 local_count_ = count;
209 for (int i = 0; i < count; i++) { 251
210 elements_.Add(FrameElement(Factory::undefined_value())); 252 if (count > 0) {
253 Comment cmnt(masm_, "[ Allocate space for locals");
254 // The locals are constants (the undefined value), but we sync them with
255 // the actual frame to allocate space for spilling them.
256 FrameElement initial_value(Factory::undefined_value());
257 initial_value.clear_dirty();
258 __ Set(eax, Immediate(Factory::undefined_value()));
259 for (int i = 0; i < count; i++) {
260 elements_.Add(initial_value);
261 stack_pointer_++;
262 __ push(eax);
263 }
211 } 264 }
212 } 265 }
213 266
214 267
215 void VirtualFrame::PushTryHandler(HandlerType type) { 268 void VirtualFrame::PushTryHandler(HandlerType type) {
216 // Grow the expression stack by handler size less two (the return address 269 // Grow the expression stack by handler size less two (the return address
217 // is already pushed by a call instruction, and PushTryHandler from the 270 // is already pushed by a call instruction, and PushTryHandler from the
218 // macro assembler will leave the top of stack in the eax register to be 271 // macro assembler will leave the top of stack in the eax register to be
219 // pushed separately). 272 // pushed separately).
220 Adjust(kHandlerSize - 2); 273 Adjust(kHandlerSize - 2);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 ASSERT(stack_pointer_ == elements_.length() - 1); 366 ASSERT(stack_pointer_ == elements_.length() - 1);
314 elements_.Add(FrameElement()); 367 elements_.Add(FrameElement());
315 stack_pointer_++; 368 stack_pointer_++;
316 __ push(immediate); 369 __ push(immediate);
317 } 370 }
318 371
319 372
320 #undef __ 373 #undef __
321 374
322 } } // namespace v8::internal 375 } } // namespace v8::internal
OLDNEW
« v8/src/virtual-frame-ia32.h ('K') | « v8/src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698