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

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

Issue 113764: Add an elements_.length() accessor to the VirtualFrame class and use... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/jump-target.cc ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 19 matching lines...) Expand all
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "register-allocator-inl.h" 31 #include "register-allocator-inl.h"
32 32
33 namespace v8 { namespace internal { 33 namespace v8 { namespace internal {
34 34
35 // ------------------------------------------------------------------------- 35 // -------------------------------------------------------------------------
36 // VirtualFrame implementation. 36 // VirtualFrame implementation.
37 37
38 // When cloned, a frame is a deep copy of the original. 38 // When cloned, a frame is a deep copy of the original.
39 VirtualFrame::VirtualFrame(VirtualFrame* original) 39 VirtualFrame::VirtualFrame(VirtualFrame* original)
40 : elements_(original->elements_.length()), 40 : elements_(original->element_count()),
41 stack_pointer_(original->stack_pointer_) { 41 stack_pointer_(original->stack_pointer_) {
42 elements_.AddAll(original->elements_); 42 elements_.AddAll(original->elements_);
43 // Copy register locations from original. 43 // Copy register locations from original.
44 memcpy(&register_locations_, 44 memcpy(&register_locations_,
45 original->register_locations_, 45 original->register_locations_,
46 sizeof(register_locations_)); 46 sizeof(register_locations_));
47 } 47 }
48 48
49 49
50 FrameElement VirtualFrame::CopyElementAt(int index) { 50 FrameElement VirtualFrame::CopyElementAt(int index) {
51 ASSERT(index >= 0); 51 ASSERT(index >= 0);
52 ASSERT(index < elements_.length()); 52 ASSERT(index < element_count());
53 53
54 FrameElement target = elements_[index]; 54 FrameElement target = elements_[index];
55 FrameElement result; 55 FrameElement result;
56 56
57 switch (target.type()) { 57 switch (target.type()) {
58 case FrameElement::CONSTANT: 58 case FrameElement::CONSTANT:
59 // We do not copy constants and instead return a fresh unsynced 59 // We do not copy constants and instead return a fresh unsynced
60 // constant. 60 // constant.
61 result = FrameElement::ConstantElement(target.handle(), 61 result = FrameElement::ConstantElement(target.handle(),
62 FrameElement::NOT_SYNCED); 62 FrameElement::NOT_SYNCED);
(...skipping 25 matching lines...) Expand all
88 return result; 88 return result;
89 } 89 }
90 90
91 91
92 // Modify the state of the virtual frame to match the actual frame by adding 92 // Modify the state of the virtual frame to match the actual frame by adding
93 // extra in-memory elements to the top of the virtual frame. The extra 93 // extra in-memory elements to the top of the virtual frame. The extra
94 // elements will be externally materialized on the actual frame (eg, by 94 // elements will be externally materialized on the actual frame (eg, by
95 // pushing an exception handler). No code is emitted. 95 // pushing an exception handler). No code is emitted.
96 void VirtualFrame::Adjust(int count) { 96 void VirtualFrame::Adjust(int count) {
97 ASSERT(count >= 0); 97 ASSERT(count >= 0);
98 ASSERT(stack_pointer_ == elements_.length() - 1); 98 ASSERT(stack_pointer_ == element_count() - 1);
99 99
100 for (int i = 0; i < count; i++) { 100 for (int i = 0; i < count; i++) {
101 elements_.Add(FrameElement::MemoryElement()); 101 elements_.Add(FrameElement::MemoryElement());
102 } 102 }
103 stack_pointer_ += count; 103 stack_pointer_ += count;
104 } 104 }
105 105
106 106
107 void VirtualFrame::ForgetElements(int count) { 107 void VirtualFrame::ForgetElements(int count) {
108 ASSERT(count >= 0); 108 ASSERT(count >= 0);
109 ASSERT(elements_.length() >= count); 109 ASSERT(element_count() >= count);
110 110
111 for (int i = 0; i < count; i++) { 111 for (int i = 0; i < count; i++) {
112 FrameElement last = elements_.RemoveLast(); 112 FrameElement last = elements_.RemoveLast();
113 if (last.is_register()) { 113 if (last.is_register()) {
114 // A hack to properly count register references for the code 114 // A hack to properly count register references for the code
115 // generator's current frame and also for other frames. The 115 // generator's current frame and also for other frames. The
116 // same code appears in PrepareMergeTo. 116 // same code appears in PrepareMergeTo.
117 if (cgen()->frame() == this) { 117 if (cgen()->frame() == this) {
118 Unuse(last.reg()); 118 Unuse(last.reg());
119 } else { 119 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } else if (index == stack_pointer_ + 1) { 165 } else if (index == stack_pointer_ + 1) {
166 SyncElementByPushing(index); 166 SyncElementByPushing(index);
167 } else { 167 } else {
168 SyncRange(stack_pointer_ + 1, index); 168 SyncRange(stack_pointer_ + 1, index);
169 } 169 }
170 } 170 }
171 171
172 172
173 // Make the type of all elements be MEMORY. 173 // Make the type of all elements be MEMORY.
174 void VirtualFrame::SpillAll() { 174 void VirtualFrame::SpillAll() {
175 for (int i = 0; i < elements_.length(); i++) { 175 for (int i = 0; i < element_count(); i++) {
176 SpillElementAt(i); 176 SpillElementAt(i);
177 } 177 }
178 } 178 }
179 179
180 180
181 void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) { 181 void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
182 // Perform state changes on this frame that will make merge to the 182 // Perform state changes on this frame that will make merge to the
183 // expected frame simpler or else increase the likelihood that his 183 // expected frame simpler or else increase the likelihood that his
184 // frame will match another. 184 // frame will match another.
185 for (int i = 0; i < elements_.length(); i++) { 185 for (int i = 0; i < element_count(); i++) {
186 FrameElement source = elements_[i]; 186 FrameElement source = elements_[i];
187 FrameElement target = expected->elements_[i]; 187 FrameElement target = expected->elements_[i];
188 188
189 if (!target.is_valid() || 189 if (!target.is_valid() ||
190 (target.is_memory() && !source.is_memory() && source.is_synced())) { 190 (target.is_memory() && !source.is_memory() && source.is_synced())) {
191 // No code needs to be generated to invalidate valid elements. 191 // No code needs to be generated to invalidate valid elements.
192 // No code needs to be generated to move values to memory if 192 // No code needs to be generated to move values to memory if
193 // they are already synced. We perform those moves here, before 193 // they are already synced. We perform those moves here, before
194 // merging. 194 // merging.
195 if (source.is_register()) { 195 if (source.is_register()) {
(...skipping 20 matching lines...) Expand all
216 elements_[i].set_static_type(target.static_type()); 216 elements_[i].set_static_type(target.static_type());
217 } 217 }
218 } 218 }
219 219
220 220
221 void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) { 221 void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) {
222 ASSERT(height() >= dropped_args); 222 ASSERT(height() >= dropped_args);
223 ASSERT(height() >= spilled_args); 223 ASSERT(height() >= spilled_args);
224 ASSERT(dropped_args <= spilled_args); 224 ASSERT(dropped_args <= spilled_args);
225 225
226 SyncRange(0, elements_.length() - 1); 226 SyncRange(0, element_count() - 1);
227 // Spill registers. 227 // Spill registers.
228 for (int i = 0; i < kNumRegisters; i++) { 228 for (int i = 0; i < kNumRegisters; i++) {
229 if (is_used(i)) { 229 if (is_used(i)) {
230 SpillElementAt(register_locations_[i]); 230 SpillElementAt(register_locations_[i]);
231 } 231 }
232 } 232 }
233 233
234 // Spill the arguments. 234 // Spill the arguments.
235 for (int i = elements_.length() - spilled_args; i < elements_.length(); i++) { 235 for (int i = element_count() - spilled_args; i < element_count(); i++) {
236 if (!elements_[i].is_memory()) { 236 if (!elements_[i].is_memory()) {
237 SpillElementAt(i); 237 SpillElementAt(i);
238 } 238 }
239 } 239 }
240 240
241 // Forget the frame elements that will be popped by the call. 241 // Forget the frame elements that will be popped by the call.
242 Forget(dropped_args); 242 Forget(dropped_args);
243 } 243 }
244 244
245 245
246 void VirtualFrame::PrepareForReturn() { 246 void VirtualFrame::PrepareForReturn() {
247 // Spill all locals. This is necessary to make sure all locals have 247 // Spill all locals. This is necessary to make sure all locals have
248 // the right value when breaking at the return site in the debugger. 248 // the right value when breaking at the return site in the debugger.
249 // Set their static type to unknown so that they will match the known 249 // Set their static type to unknown so that they will match the known
250 // return frame. 250 // return frame.
251 for (int i = 0; i < expression_base_index(); i++) { 251 for (int i = 0; i < expression_base_index(); i++) {
252 SpillElementAt(i); 252 SpillElementAt(i);
253 elements_[i].set_static_type(StaticType::unknown()); 253 elements_[i].set_static_type(StaticType::unknown());
254 } 254 }
255 } 255 }
256 256
257 257
258 void VirtualFrame::SetElementAt(int index, Result* value) { 258 void VirtualFrame::SetElementAt(int index, Result* value) {
259 int frame_index = elements_.length() - index - 1; 259 int frame_index = element_count() - index - 1;
260 ASSERT(frame_index >= 0); 260 ASSERT(frame_index >= 0);
261 ASSERT(frame_index < elements_.length()); 261 ASSERT(frame_index < element_count());
262 ASSERT(value->is_valid()); 262 ASSERT(value->is_valid());
263 FrameElement original = elements_[frame_index]; 263 FrameElement original = elements_[frame_index];
264 264
265 // Early exit if the element is the same as the one being set. 265 // Early exit if the element is the same as the one being set.
266 bool same_register = original.is_register() 266 bool same_register = original.is_register()
267 && value->is_register() 267 && value->is_register()
268 && original.reg().is(value->reg()); 268 && original.reg().is(value->reg());
269 bool same_constant = original.is_constant() 269 bool same_constant = original.is_constant()
270 && value->is_constant() 270 && value->is_constant()
271 && original.handle().is_identical_to(value->handle()); 271 && original.handle().is_identical_to(value->handle());
(...skipping 20 matching lines...) Expand all
292 // There was an early bailout for the case of setting a 292 // There was an early bailout for the case of setting a
293 // register element to itself. 293 // register element to itself.
294 ASSERT(i != frame_index); 294 ASSERT(i != frame_index);
295 elements_[frame_index] = elements_[i]; 295 elements_[frame_index] = elements_[i];
296 elements_[i] = CopyElementAt(frame_index); 296 elements_[i] = CopyElementAt(frame_index);
297 if (elements_[frame_index].is_synced()) { 297 if (elements_[frame_index].is_synced()) {
298 elements_[i].set_sync(); 298 elements_[i].set_sync();
299 } 299 }
300 elements_[frame_index].clear_sync(); 300 elements_[frame_index].clear_sync();
301 register_locations_[value->reg().code()] = frame_index; 301 register_locations_[value->reg().code()] = frame_index;
302 for (int j = i + 1; j < elements_.length(); j++) { 302 for (int j = i + 1; j < element_count(); j++) {
303 if (elements_[j].is_copy() && elements_[j].index() == i) { 303 if (elements_[j].is_copy() && elements_[j].index() == i) {
304 elements_[j].set_index(frame_index); 304 elements_[j].set_index(frame_index);
305 } 305 }
306 } 306 }
307 } 307 }
308 } else { 308 } else {
309 // The register value->reg() was not already used on the frame. 309 // The register value->reg() was not already used on the frame.
310 Use(value->reg(), frame_index); 310 Use(value->reg(), frame_index);
311 elements_[frame_index] = 311 elements_[frame_index] =
312 FrameElement::RegisterElement(value->reg(), 312 FrameElement::RegisterElement(value->reg(),
(...skipping 15 matching lines...) Expand all
328 } 328 }
329 329
330 330
331 void VirtualFrame::Push(Register reg, StaticType static_type) { 331 void VirtualFrame::Push(Register reg, StaticType static_type) {
332 if (is_used(reg)) { 332 if (is_used(reg)) {
333 int index = register_index(reg); 333 int index = register_index(reg);
334 FrameElement element = CopyElementAt(index); 334 FrameElement element = CopyElementAt(index);
335 ASSERT(static_type.merge(element.static_type()) == element.static_type()); 335 ASSERT(static_type.merge(element.static_type()) == element.static_type());
336 elements_.Add(element); 336 elements_.Add(element);
337 } else { 337 } else {
338 Use(reg, elements_.length()); 338 Use(reg, element_count());
339 FrameElement element = 339 FrameElement element =
340 FrameElement::RegisterElement(reg, 340 FrameElement::RegisterElement(reg,
341 FrameElement::NOT_SYNCED, 341 FrameElement::NOT_SYNCED,
342 static_type); 342 static_type);
343 elements_.Add(element); 343 elements_.Add(element);
344 } 344 }
345 } 345 }
346 346
347 347
348 void VirtualFrame::Push(Handle<Object> value) { 348 void VirtualFrame::Push(Handle<Object> value) {
(...skipping 14 matching lines...) Expand all
363 } 363 }
364 364
365 365
366 bool VirtualFrame::Equals(VirtualFrame* other) { 366 bool VirtualFrame::Equals(VirtualFrame* other) {
367 #ifdef DEBUG 367 #ifdef DEBUG
368 for (int i = 0; i < kNumRegisters; i++) { 368 for (int i = 0; i < kNumRegisters; i++) {
369 if (register_locations_[i] != other->register_locations_[i]) { 369 if (register_locations_[i] != other->register_locations_[i]) {
370 return false; 370 return false;
371 } 371 }
372 } 372 }
373 if (elements_.length() != other->elements_.length()) return false; 373 if (element_count() != other->element_count()) return false;
374 #endif 374 #endif
375 if (stack_pointer_ != other->stack_pointer_) return false; 375 if (stack_pointer_ != other->stack_pointer_) return false;
376 for (int i = 0; i < elements_.length(); i++) { 376 for (int i = 0; i < element_count(); i++) {
377 if (!elements_[i].Equals(other->elements_[i])) return false; 377 if (!elements_[i].Equals(other->elements_[i])) return false;
378 } 378 }
379 379
380 return true; 380 return true;
381 } 381 }
382 382
383 383
384 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. 384 // Specialization of List::ResizeAdd to non-inlined version for FrameElements.
385 // The function ResizeAdd becomes a real function, whose implementation is the 385 // The function ResizeAdd becomes a real function, whose implementation is the
386 // inlined ResizeAddInternal. 386 // inlined ResizeAddInternal.
387 template <> 387 template <>
388 void List<FrameElement, 388 void List<FrameElement,
389 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { 389 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) {
390 ResizeAddInternal(element); 390 ResizeAddInternal(element);
391 } 391 }
392 392
393 } } // namespace v8::internal 393 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jump-target.cc ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698