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

Side by Side Diff: src/x64/codegen-x64.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/x64/codegen-x64.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 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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 271
272 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); 272 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT);
273 frame_->EmitPush(rsi); // The context is the first argument. 273 frame_->EmitPush(rsi); // The context is the first argument.
274 frame_->EmitPush(kScratchRegister); 274 frame_->EmitPush(kScratchRegister);
275 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0)); 275 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0));
276 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 276 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
277 // Return value is ignored. 277 // Return value is ignored.
278 } 278 }
279 279
280 280
281 void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) { 281 void CodeGenerator::Generate(FunctionLiteral* function,
282 Mode mode,
283 CompilationInfo* info) {
282 // Record the position for debugging purposes. 284 // Record the position for debugging purposes.
283 CodeForFunctionPosition(function); 285 CodeForFunctionPosition(function);
284 ZoneList<Statement*>* body = function->body(); 286 ZoneList<Statement*>* body = function->body();
285 287
286 // Initialize state. 288 // Initialize state.
287 ASSERT(scope_ == NULL); 289 ASSERT(scope_ == NULL);
288 scope_ = function->scope(); 290 scope_ = function->scope();
289 ASSERT(allocator_ == NULL); 291 ASSERT(allocator_ == NULL);
290 RegisterAllocator register_allocator(this); 292 RegisterAllocator register_allocator(this);
291 allocator_ = &register_allocator; 293 allocator_ = &register_allocator;
(...skipping 19 matching lines...) Expand all
311 HistogramTimerScope codegen_timer(&Counters::code_generation); 313 HistogramTimerScope codegen_timer(&Counters::code_generation);
312 CodeGenState state(this); 314 CodeGenState state(this);
313 315
314 // Entry: 316 // Entry:
315 // Stack: receiver, arguments, return address. 317 // Stack: receiver, arguments, return address.
316 // rbp: caller's frame pointer 318 // rbp: caller's frame pointer
317 // rsp: stack pointer 319 // rsp: stack pointer
318 // rdi: called JS function 320 // rdi: called JS function
319 // rsi: callee's context 321 // rsi: callee's context
320 allocator_->Initialize(); 322 allocator_->Initialize();
321 frame_->Enter();
322 323
323 // Allocate space for locals and initialize them. 324 if (mode == PRIMARY) {
324 frame_->AllocateStackSlots(); 325 frame_->Enter();
326
327 // Allocate space for locals and initialize them.
328 frame_->AllocateStackSlots();
329
330 // Allocate the local context if needed.
331 int heap_slots = scope_->num_heap_slots();
332 if (heap_slots > 0) {
333 Comment cmnt(masm_, "[ allocate local context");
334 // Allocate local context.
335 // Get outer context and create a new context based on it.
336 frame_->PushFunction();
337 Result context;
338 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
339 FastNewContextStub stub(heap_slots);
340 context = frame_->CallStub(&stub, 1);
341 } else {
342 context = frame_->CallRuntime(Runtime::kNewContext, 1);
343 }
344
345 // Update context local.
346 frame_->SaveContextRegister();
347
348 // Verify that the runtime call result and rsi agree.
349 if (FLAG_debug_code) {
350 __ cmpq(context.reg(), rsi);
351 __ Assert(equal, "Runtime::NewContext should end up in rsi");
352 }
353 }
354
355 // TODO(1241774): Improve this code:
356 // 1) only needed if we have a context
357 // 2) no need to recompute context ptr every single time
358 // 3) don't copy parameter operand code from SlotOperand!
359 {
360 Comment cmnt2(masm_, "[ copy context parameters into .context");
361
362 // Note that iteration order is relevant here! If we have the same
363 // parameter twice (e.g., function (x, y, x)), and that parameter
364 // needs to be copied into the context, it must be the last argument
365 // passed to the parameter that needs to be copied. This is a rare
366 // case so we don't check for it, instead we rely on the copying
367 // order: such a parameter is copied repeatedly into the same
368 // context location and thus the last value is what is seen inside
369 // the function.
370 for (int i = 0; i < scope_->num_parameters(); i++) {
371 Variable* par = scope_->parameter(i);
372 Slot* slot = par->slot();
373 if (slot != NULL && slot->type() == Slot::CONTEXT) {
374 // The use of SlotOperand below is safe in unspilled code
375 // because the slot is guaranteed to be a context slot.
376 //
377 // There are no parameters in the global scope.
378 ASSERT(!scope_->is_global_scope());
379 frame_->PushParameterAt(i);
380 Result value = frame_->Pop();
381 value.ToRegister();
382
383 // SlotOperand loads context.reg() with the context object
384 // stored to, used below in RecordWrite.
385 Result context = allocator_->Allocate();
386 ASSERT(context.is_valid());
387 __ movq(SlotOperand(slot, context.reg()), value.reg());
388 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
389 Result scratch = allocator_->Allocate();
390 ASSERT(scratch.is_valid());
391 frame_->Spill(context.reg());
392 frame_->Spill(value.reg());
393 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
394 }
395 }
396 }
397
398 // Store the arguments object. This must happen after context
399 // initialization because the arguments object may be stored in
400 // the context.
401 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
402 StoreArgumentsObject(true);
403 }
404
405 // Initialize ThisFunction reference if present.
406 if (scope_->is_function_scope() && scope_->function() != NULL) {
407 frame_->Push(Factory::the_hole_value());
408 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
409 }
410 } else {
411 // When used as the secondary compiler for splitting, rbp, rsi,
412 // and rdi have been pushed on the stack. Adjust the virtual
413 // frame to match this state.
414 frame_->Adjust(3);
415 allocator_->Unuse(rdi);
416 }
417
325 // Initialize the function return target after the locals are set 418 // Initialize the function return target after the locals are set
326 // up, because it needs the expected frame height from the frame. 419 // up, because it needs the expected frame height from the frame.
327 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 420 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
328 function_return_is_shadowed_ = false; 421 function_return_is_shadowed_ = false;
329 422
330 // Allocate the local context if needed.
331 int heap_slots = scope_->num_heap_slots();
332 if (heap_slots > 0) {
333 Comment cmnt(masm_, "[ allocate local context");
334 // Allocate local context.
335 // Get outer context and create a new context based on it.
336 frame_->PushFunction();
337 Result context;
338 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
339 FastNewContextStub stub(heap_slots);
340 context = frame_->CallStub(&stub, 1);
341 } else {
342 context = frame_->CallRuntime(Runtime::kNewContext, 1);
343 }
344
345 // Update context local.
346 frame_->SaveContextRegister();
347
348 // Verify that the runtime call result and rsi agree.
349 if (FLAG_debug_code) {
350 __ cmpq(context.reg(), rsi);
351 __ Assert(equal, "Runtime::NewContext should end up in rsi");
352 }
353 }
354
355 // TODO(1241774): Improve this code:
356 // 1) only needed if we have a context
357 // 2) no need to recompute context ptr every single time
358 // 3) don't copy parameter operand code from SlotOperand!
359 {
360 Comment cmnt2(masm_, "[ copy context parameters into .context");
361
362 // Note that iteration order is relevant here! If we have the same
363 // parameter twice (e.g., function (x, y, x)), and that parameter
364 // needs to be copied into the context, it must be the last argument
365 // passed to the parameter that needs to be copied. This is a rare
366 // case so we don't check for it, instead we rely on the copying
367 // order: such a parameter is copied repeatedly into the same
368 // context location and thus the last value is what is seen inside
369 // the function.
370 for (int i = 0; i < scope_->num_parameters(); i++) {
371 Variable* par = scope_->parameter(i);
372 Slot* slot = par->slot();
373 if (slot != NULL && slot->type() == Slot::CONTEXT) {
374 // The use of SlotOperand below is safe in unspilled code
375 // because the slot is guaranteed to be a context slot.
376 //
377 // There are no parameters in the global scope.
378 ASSERT(!scope_->is_global_scope());
379 frame_->PushParameterAt(i);
380 Result value = frame_->Pop();
381 value.ToRegister();
382
383 // SlotOperand loads context.reg() with the context object
384 // stored to, used below in RecordWrite.
385 Result context = allocator_->Allocate();
386 ASSERT(context.is_valid());
387 __ movq(SlotOperand(slot, context.reg()), value.reg());
388 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
389 Result scratch = allocator_->Allocate();
390 ASSERT(scratch.is_valid());
391 frame_->Spill(context.reg());
392 frame_->Spill(value.reg());
393 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
394 }
395 }
396 }
397
398 // Store the arguments object. This must happen after context
399 // initialization because the arguments object may be stored in
400 // the context.
401 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
402 StoreArgumentsObject(true);
403 }
404
405 // Initialize ThisFunction reference if present.
406 if (scope_->is_function_scope() && scope_->function() != NULL) {
407 frame_->Push(Factory::the_hole_value());
408 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
409 }
410
411 // Generate code to 'execute' declarations and initialize functions 423 // Generate code to 'execute' declarations and initialize functions
412 // (source elements). In case of an illegal redeclaration we need to 424 // (source elements). In case of an illegal redeclaration we need to
413 // handle that instead of processing the declarations. 425 // handle that instead of processing the declarations.
414 if (scope_->HasIllegalRedeclaration()) { 426 if (scope_->HasIllegalRedeclaration()) {
415 Comment cmnt(masm_, "[ illegal redeclarations"); 427 Comment cmnt(masm_, "[ illegal redeclarations");
416 scope_->VisitIllegalRedeclaration(this); 428 scope_->VisitIllegalRedeclaration(this);
417 } else { 429 } else {
418 Comment cmnt(masm_, "[ declarations"); 430 Comment cmnt(masm_, "[ declarations");
419 ProcessDeclarations(scope_->declarations()); 431 ProcessDeclarations(scope_->declarations());
420 // Bail out if a stack-overflow exception occurred when processing 432 // Bail out if a stack-overflow exception occurred when processing
(...skipping 8765 matching lines...) Expand 10 before | Expand all | Expand 10 after
9186 // Call the function from C++. 9198 // Call the function from C++.
9187 return FUNCTION_CAST<ModuloFunction>(buffer); 9199 return FUNCTION_CAST<ModuloFunction>(buffer);
9188 } 9200 }
9189 9201
9190 #endif 9202 #endif
9191 9203
9192 9204
9193 #undef __ 9205 #undef __
9194 9206
9195 } } // namespace v8::internal 9207 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698