| 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 |