OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 EmitProfilingCounterReset(); | 379 EmitProfilingCounterReset(); |
380 | 380 |
381 __ bind(&ok); | 381 __ bind(&ok); |
382 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 382 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
383 // Record a mapping of the OSR id to this PC. This is used if the OSR | 383 // Record a mapping of the OSR id to this PC. This is used if the OSR |
384 // entry becomes the target of a bailout. We don't expect it to be, but | 384 // entry becomes the target of a bailout. We don't expect it to be, but |
385 // we want it to work if it is. | 385 // we want it to work if it is. |
386 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); | 386 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); |
387 } | 387 } |
388 | 388 |
| 389 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( |
| 390 bool is_tail_call) { |
| 391 // Pretend that the exit is a backwards jump to the entry. |
| 392 int weight = 1; |
| 393 if (info_->ShouldSelfOptimize()) { |
| 394 weight = FLAG_interrupt_budget / FLAG_self_opt_count; |
| 395 } else { |
| 396 int distance = masm_->pc_offset(); |
| 397 weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier)); |
| 398 } |
| 399 EmitProfilingCounterDecrement(weight); |
| 400 Label ok; |
| 401 __ j(positive, &ok, Label::kNear); |
| 402 // Don't need to save result register if we are going to do a tail call. |
| 403 if (!is_tail_call) { |
| 404 __ push(eax); |
| 405 } |
| 406 __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); |
| 407 if (!is_tail_call) { |
| 408 __ pop(eax); |
| 409 } |
| 410 EmitProfilingCounterReset(); |
| 411 __ bind(&ok); |
| 412 } |
389 | 413 |
390 void FullCodeGenerator::EmitReturnSequence() { | 414 void FullCodeGenerator::EmitReturnSequence() { |
391 Comment cmnt(masm_, "[ Return sequence"); | 415 Comment cmnt(masm_, "[ Return sequence"); |
392 if (return_label_.is_bound()) { | 416 if (return_label_.is_bound()) { |
393 __ jmp(&return_label_); | 417 __ jmp(&return_label_); |
394 } else { | 418 } else { |
395 // Common return label | 419 // Common return label |
396 __ bind(&return_label_); | 420 __ bind(&return_label_); |
397 if (FLAG_trace) { | 421 if (FLAG_trace) { |
398 __ push(eax); | 422 __ push(eax); |
399 __ CallRuntime(Runtime::kTraceExit); | 423 __ CallRuntime(Runtime::kTraceExit); |
400 } | 424 } |
401 // Pretend that the exit is a backwards jump to the entry. | 425 EmitProfilingCounterHandlingForReturnSequence(false); |
402 int weight = 1; | |
403 if (info_->ShouldSelfOptimize()) { | |
404 weight = FLAG_interrupt_budget / FLAG_self_opt_count; | |
405 } else { | |
406 int distance = masm_->pc_offset(); | |
407 weight = Min(kMaxBackEdgeWeight, | |
408 Max(1, distance / kCodeSizeMultiplier)); | |
409 } | |
410 EmitProfilingCounterDecrement(weight); | |
411 Label ok; | |
412 __ j(positive, &ok, Label::kNear); | |
413 __ push(eax); | |
414 __ call(isolate()->builtins()->InterruptCheck(), | |
415 RelocInfo::CODE_TARGET); | |
416 __ pop(eax); | |
417 EmitProfilingCounterReset(); | |
418 __ bind(&ok); | |
419 | 426 |
420 SetReturnPosition(literal()); | 427 SetReturnPosition(literal()); |
421 __ leave(); | 428 __ leave(); |
422 | 429 |
423 int arg_count = info_->scope()->num_parameters() + 1; | 430 int arg_count = info_->scope()->num_parameters() + 1; |
424 int arguments_bytes = arg_count * kPointerSize; | 431 int arguments_bytes = arg_count * kPointerSize; |
425 __ Ret(arguments_bytes, ecx); | 432 __ Ret(arguments_bytes, ecx); |
426 } | 433 } |
427 } | 434 } |
428 | 435 |
(...skipping 2204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2633 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 2640 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
2634 // Load the arguments. | 2641 // Load the arguments. |
2635 ZoneList<Expression*>* args = expr->arguments(); | 2642 ZoneList<Expression*>* args = expr->arguments(); |
2636 int arg_count = args->length(); | 2643 int arg_count = args->length(); |
2637 for (int i = 0; i < arg_count; i++) { | 2644 for (int i = 0; i < arg_count; i++) { |
2638 VisitForStackValue(args->at(i)); | 2645 VisitForStackValue(args->at(i)); |
2639 } | 2646 } |
2640 | 2647 |
2641 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2648 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2642 SetCallPosition(expr); | 2649 SetCallPosition(expr); |
| 2650 if (expr->tail_call_mode() == TailCallMode::kAllow) { |
| 2651 if (FLAG_trace) { |
| 2652 __ CallRuntime(Runtime::kTraceTailCall); |
| 2653 } |
| 2654 // Update profiling counters before the tail call since we will |
| 2655 // not return to this function. |
| 2656 EmitProfilingCounterHandlingForReturnSequence(true); |
| 2657 } |
2643 Handle<Code> ic = | 2658 Handle<Code> ic = |
2644 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2659 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2645 .code(); | 2660 .code(); |
2646 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2661 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2647 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2662 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2648 // Don't assign a type feedback id to the IC, since type feedback is provided | 2663 // Don't assign a type feedback id to the IC, since type feedback is provided |
2649 // by the vector above. | 2664 // by the vector above. |
2650 CallIC(ic); | 2665 CallIC(ic); |
2651 | 2666 |
2652 RecordJSReturnSite(expr); | 2667 RecordJSReturnSite(expr); |
(...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4591 Assembler::target_address_at(call_target_address, | 4606 Assembler::target_address_at(call_target_address, |
4592 unoptimized_code)); | 4607 unoptimized_code)); |
4593 return OSR_AFTER_STACK_CHECK; | 4608 return OSR_AFTER_STACK_CHECK; |
4594 } | 4609 } |
4595 | 4610 |
4596 | 4611 |
4597 } // namespace internal | 4612 } // namespace internal |
4598 } // namespace v8 | 4613 } // namespace v8 |
4599 | 4614 |
4600 #endif // V8_TARGET_ARCH_IA32 | 4615 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |