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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 569010: Use the virtual-frame based optimizing compiler for split-compilation... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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/ia32/codegen-ia32.h ('k') | src/x64/codegen-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 in_spilled_code_(false) { 119 in_spilled_code_(false) {
120 } 120 }
121 121
122 122
123 // Calling conventions: 123 // Calling conventions:
124 // ebp: caller's frame pointer 124 // ebp: caller's frame pointer
125 // esp: stack pointer 125 // esp: stack pointer
126 // edi: called JS function 126 // edi: called JS function
127 // esi: callee's context 127 // esi: callee's context
128 128
129 void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { 129 void CodeGenerator::Generate(FunctionLiteral* fun,
130 Mode mode,
131 CompilationInfo* info) {
130 // Record the position for debugging purposes. 132 // Record the position for debugging purposes.
131 CodeForFunctionPosition(fun); 133 CodeForFunctionPosition(fun);
132 134
133 ZoneList<Statement*>* body = fun->body(); 135 ZoneList<Statement*>* body = fun->body();
134 136
135 // Initialize state. 137 // Initialize state.
136 ASSERT(scope_ == NULL); 138 ASSERT(scope_ == NULL);
137 scope_ = fun->scope(); 139 scope_ = fun->scope();
138 ASSERT(allocator_ == NULL); 140 ASSERT(allocator_ == NULL);
139 RegisterAllocator register_allocator(this); 141 RegisterAllocator register_allocator(this);
(...skipping 20 matching lines...) Expand all
160 HistogramTimerScope codegen_timer(&Counters::code_generation); 162 HistogramTimerScope codegen_timer(&Counters::code_generation);
161 CodeGenState state(this); 163 CodeGenState state(this);
162 164
163 // Entry: 165 // Entry:
164 // Stack: receiver, arguments, return address. 166 // Stack: receiver, arguments, return address.
165 // ebp: caller's frame pointer 167 // ebp: caller's frame pointer
166 // esp: stack pointer 168 // esp: stack pointer
167 // edi: called JS function 169 // edi: called JS function
168 // esi: callee's context 170 // esi: callee's context
169 allocator_->Initialize(); 171 allocator_->Initialize();
170 frame_->Enter();
171 172
172 // Allocate space for locals and initialize them. 173 if (mode == PRIMARY) {
173 frame_->AllocateStackSlots(); 174 frame_->Enter();
175
176 // Allocate space for locals and initialize them.
177 frame_->AllocateStackSlots();
178
179 // Allocate the local context if needed.
180 int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
181 if (heap_slots > 0) {
182 Comment cmnt(masm_, "[ allocate local context");
183 // Allocate local context.
184 // Get outer context and create a new context based on it.
185 frame_->PushFunction();
186 Result context;
187 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
188 FastNewContextStub stub(heap_slots);
189 context = frame_->CallStub(&stub, 1);
190 } else {
191 context = frame_->CallRuntime(Runtime::kNewContext, 1);
192 }
193
194 // Update context local.
195 frame_->SaveContextRegister();
196
197 // Verify that the runtime call result and esi agree.
198 if (FLAG_debug_code) {
199 __ cmp(context.reg(), Operand(esi));
200 __ Assert(equal, "Runtime::NewContext should end up in esi");
201 }
202 }
203
204 // TODO(1241774): Improve this code:
205 // 1) only needed if we have a context
206 // 2) no need to recompute context ptr every single time
207 // 3) don't copy parameter operand code from SlotOperand!
208 {
209 Comment cmnt2(masm_, "[ copy context parameters into .context");
210
211 // Note that iteration order is relevant here! If we have the same
212 // parameter twice (e.g., function (x, y, x)), and that parameter
213 // needs to be copied into the context, it must be the last argument
214 // passed to the parameter that needs to be copied. This is a rare
215 // case so we don't check for it, instead we rely on the copying
216 // order: such a parameter is copied repeatedly into the same
217 // context location and thus the last value is what is seen inside
218 // the function.
219 for (int i = 0; i < scope_->num_parameters(); i++) {
220 Variable* par = scope_->parameter(i);
221 Slot* slot = par->slot();
222 if (slot != NULL && slot->type() == Slot::CONTEXT) {
223 // The use of SlotOperand below is safe in unspilled code
224 // because the slot is guaranteed to be a context slot.
225 //
226 // There are no parameters in the global scope.
227 ASSERT(!scope_->is_global_scope());
228 frame_->PushParameterAt(i);
229 Result value = frame_->Pop();
230 value.ToRegister();
231
232 // SlotOperand loads context.reg() with the context object
233 // stored to, used below in RecordWrite.
234 Result context = allocator_->Allocate();
235 ASSERT(context.is_valid());
236 __ mov(SlotOperand(slot, context.reg()), value.reg());
237 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
238 Result scratch = allocator_->Allocate();
239 ASSERT(scratch.is_valid());
240 frame_->Spill(context.reg());
241 frame_->Spill(value.reg());
242 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
243 }
244 }
245 }
246
247 // Store the arguments object. This must happen after context
248 // initialization because the arguments object may be stored in
249 // the context.
250 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
251 StoreArgumentsObject(true);
252 }
253
254 // Initialize ThisFunction reference if present.
255 if (scope_->is_function_scope() && scope_->function() != NULL) {
256 frame_->Push(Factory::the_hole_value());
257 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
258 }
259 } else {
260 // When used as the secondary compiler for splitting, ebp, esi,
261 // and edi have been pushed on the stack. Adjust the virtual
262 // frame to match this state.
263 frame_->Adjust(3);
264 allocator_->Unuse(edi);
265 }
266
174 // Initialize the function return target after the locals are set 267 // Initialize the function return target after the locals are set
175 // up, because it needs the expected frame height from the frame. 268 // up, because it needs the expected frame height from the frame.
176 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 269 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
177 function_return_is_shadowed_ = false; 270 function_return_is_shadowed_ = false;
178 271
179 // Allocate the local context if needed.
180 int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
181 if (heap_slots > 0) {
182 Comment cmnt(masm_, "[ allocate local context");
183 // Allocate local context.
184 // Get outer context and create a new context based on it.
185 frame_->PushFunction();
186 Result context;
187 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
188 FastNewContextStub stub(heap_slots);
189 context = frame_->CallStub(&stub, 1);
190 } else {
191 context = frame_->CallRuntime(Runtime::kNewContext, 1);
192 }
193
194 // Update context local.
195 frame_->SaveContextRegister();
196
197 // Verify that the runtime call result and esi agree.
198 if (FLAG_debug_code) {
199 __ cmp(context.reg(), Operand(esi));
200 __ Assert(equal, "Runtime::NewContext should end up in esi");
201 }
202 }
203
204 // TODO(1241774): Improve this code:
205 // 1) only needed if we have a context
206 // 2) no need to recompute context ptr every single time
207 // 3) don't copy parameter operand code from SlotOperand!
208 {
209 Comment cmnt2(masm_, "[ copy context parameters into .context");
210
211 // Note that iteration order is relevant here! If we have the same
212 // parameter twice (e.g., function (x, y, x)), and that parameter
213 // needs to be copied into the context, it must be the last argument
214 // passed to the parameter that needs to be copied. This is a rare
215 // case so we don't check for it, instead we rely on the copying
216 // order: such a parameter is copied repeatedly into the same
217 // context location and thus the last value is what is seen inside
218 // the function.
219 for (int i = 0; i < scope_->num_parameters(); i++) {
220 Variable* par = scope_->parameter(i);
221 Slot* slot = par->slot();
222 if (slot != NULL && slot->type() == Slot::CONTEXT) {
223 // The use of SlotOperand below is safe in unspilled code
224 // because the slot is guaranteed to be a context slot.
225 //
226 // There are no parameters in the global scope.
227 ASSERT(!scope_->is_global_scope());
228 frame_->PushParameterAt(i);
229 Result value = frame_->Pop();
230 value.ToRegister();
231
232 // SlotOperand loads context.reg() with the context object
233 // stored to, used below in RecordWrite.
234 Result context = allocator_->Allocate();
235 ASSERT(context.is_valid());
236 __ mov(SlotOperand(slot, context.reg()), value.reg());
237 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
238 Result scratch = allocator_->Allocate();
239 ASSERT(scratch.is_valid());
240 frame_->Spill(context.reg());
241 frame_->Spill(value.reg());
242 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
243 }
244 }
245 }
246
247 // Store the arguments object. This must happen after context
248 // initialization because the arguments object may be stored in
249 // the context.
250 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
251 StoreArgumentsObject(true);
252 }
253
254 // Initialize ThisFunction reference if present.
255 if (scope_->is_function_scope() && scope_->function() != NULL) {
256 frame_->Push(Factory::the_hole_value());
257 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
258 }
259
260 // Generate code to 'execute' declarations and initialize functions 272 // Generate code to 'execute' declarations and initialize functions
261 // (source elements). In case of an illegal redeclaration we need to 273 // (source elements). In case of an illegal redeclaration we need to
262 // handle that instead of processing the declarations. 274 // handle that instead of processing the declarations.
263 if (scope_->HasIllegalRedeclaration()) { 275 if (scope_->HasIllegalRedeclaration()) {
264 Comment cmnt(masm_, "[ illegal redeclarations"); 276 Comment cmnt(masm_, "[ illegal redeclarations");
265 scope_->VisitIllegalRedeclaration(this); 277 scope_->VisitIllegalRedeclaration(this);
266 } else { 278 } else {
267 Comment cmnt(masm_, "[ declarations"); 279 Comment cmnt(masm_, "[ declarations");
268 ProcessDeclarations(scope_->declarations()); 280 ProcessDeclarations(scope_->declarations());
269 // Bail out if a stack-overflow exception occurred when processing 281 // Bail out if a stack-overflow exception occurred when processing
(...skipping 9820 matching lines...) Expand 10 before | Expand all | Expand 10 after
10090 10102
10091 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 10103 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
10092 // tagged as a small integer. 10104 // tagged as a small integer.
10093 __ bind(&runtime); 10105 __ bind(&runtime);
10094 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 10106 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
10095 } 10107 }
10096 10108
10097 #undef __ 10109 #undef __
10098 10110
10099 } } // namespace v8::internal 10111 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698