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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 } | 382 } |
383 __ bind(&ok); | 383 __ bind(&ok); |
384 | 384 |
385 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 385 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
386 // Record a mapping of the OSR id to this PC. This is used if the OSR | 386 // Record a mapping of the OSR id to this PC. This is used if the OSR |
387 // entry becomes the target of a bailout. We don't expect it to be, but | 387 // entry becomes the target of a bailout. We don't expect it to be, but |
388 // we want it to work if it is. | 388 // we want it to work if it is. |
389 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); | 389 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); |
390 } | 390 } |
391 | 391 |
| 392 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( |
| 393 bool is_tail_call) { |
| 394 // Pretend that the exit is a backwards jump to the entry. |
| 395 int weight = 1; |
| 396 if (info_->ShouldSelfOptimize()) { |
| 397 weight = FLAG_interrupt_budget / FLAG_self_opt_count; |
| 398 } else { |
| 399 int distance = masm_->pc_offset(); |
| 400 weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier)); |
| 401 } |
| 402 EmitProfilingCounterDecrement(weight); |
| 403 Label ok; |
| 404 __ j(positive, &ok, Label::kNear); |
| 405 // Don't need to save result register if we are going to do a tail call. |
| 406 if (!is_tail_call) { |
| 407 __ Push(rax); |
| 408 } |
| 409 __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); |
| 410 if (!is_tail_call) { |
| 411 __ Pop(rax); |
| 412 } |
| 413 EmitProfilingCounterReset(); |
| 414 __ bind(&ok); |
| 415 } |
392 | 416 |
393 void FullCodeGenerator::EmitReturnSequence() { | 417 void FullCodeGenerator::EmitReturnSequence() { |
394 Comment cmnt(masm_, "[ Return sequence"); | 418 Comment cmnt(masm_, "[ Return sequence"); |
395 if (return_label_.is_bound()) { | 419 if (return_label_.is_bound()) { |
396 __ jmp(&return_label_); | 420 __ jmp(&return_label_); |
397 } else { | 421 } else { |
398 __ bind(&return_label_); | 422 __ bind(&return_label_); |
399 if (FLAG_trace) { | 423 if (FLAG_trace) { |
400 __ Push(rax); | 424 __ Push(rax); |
401 __ CallRuntime(Runtime::kTraceExit); | 425 __ CallRuntime(Runtime::kTraceExit); |
402 } | 426 } |
403 // Pretend that the exit is a backwards jump to the entry. | 427 EmitProfilingCounterHandlingForReturnSequence(false); |
404 int weight = 1; | |
405 if (info_->ShouldSelfOptimize()) { | |
406 weight = FLAG_interrupt_budget / FLAG_self_opt_count; | |
407 } else { | |
408 int distance = masm_->pc_offset(); | |
409 weight = Min(kMaxBackEdgeWeight, | |
410 Max(1, distance / kCodeSizeMultiplier)); | |
411 } | |
412 EmitProfilingCounterDecrement(weight); | |
413 Label ok; | |
414 __ j(positive, &ok, Label::kNear); | |
415 __ Push(rax); | |
416 __ call(isolate()->builtins()->InterruptCheck(), | |
417 RelocInfo::CODE_TARGET); | |
418 __ Pop(rax); | |
419 EmitProfilingCounterReset(); | |
420 __ bind(&ok); | |
421 | 428 |
422 SetReturnPosition(literal()); | 429 SetReturnPosition(literal()); |
423 __ leave(); | 430 __ leave(); |
424 | 431 |
425 int arg_count = info_->scope()->num_parameters() + 1; | 432 int arg_count = info_->scope()->num_parameters() + 1; |
426 int arguments_bytes = arg_count * kPointerSize; | 433 int arguments_bytes = arg_count * kPointerSize; |
427 __ Ret(arguments_bytes, rcx); | 434 __ Ret(arguments_bytes, rcx); |
428 } | 435 } |
429 } | 436 } |
430 | 437 |
(...skipping 2188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 2626 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
2620 // Load the arguments. | 2627 // Load the arguments. |
2621 ZoneList<Expression*>* args = expr->arguments(); | 2628 ZoneList<Expression*>* args = expr->arguments(); |
2622 int arg_count = args->length(); | 2629 int arg_count = args->length(); |
2623 for (int i = 0; i < arg_count; i++) { | 2630 for (int i = 0; i < arg_count; i++) { |
2624 VisitForStackValue(args->at(i)); | 2631 VisitForStackValue(args->at(i)); |
2625 } | 2632 } |
2626 | 2633 |
2627 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 2634 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
2628 SetCallPosition(expr); | 2635 SetCallPosition(expr); |
| 2636 if (expr->tail_call_mode() == TailCallMode::kAllow) { |
| 2637 if (FLAG_trace) { |
| 2638 __ CallRuntime(Runtime::kTraceTailCall); |
| 2639 } |
| 2640 // Update profiling counters before the tail call since we will |
| 2641 // not return to this function. |
| 2642 EmitProfilingCounterHandlingForReturnSequence(true); |
| 2643 } |
2629 Handle<Code> ic = | 2644 Handle<Code> ic = |
2630 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2645 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2631 .code(); | 2646 .code(); |
2632 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); | 2647 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); |
2633 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2648 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2634 // Don't assign a type feedback id to the IC, since type feedback is provided | 2649 // Don't assign a type feedback id to the IC, since type feedback is provided |
2635 // by the vector above. | 2650 // by the vector above. |
2636 CallIC(ic); | 2651 CallIC(ic); |
2637 | 2652 |
2638 RecordJSReturnSite(expr); | 2653 RecordJSReturnSite(expr); |
(...skipping 1953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4592 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4607 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4593 Assembler::target_address_at(call_target_address, | 4608 Assembler::target_address_at(call_target_address, |
4594 unoptimized_code)); | 4609 unoptimized_code)); |
4595 return OSR_AFTER_STACK_CHECK; | 4610 return OSR_AFTER_STACK_CHECK; |
4596 } | 4611 } |
4597 | 4612 |
4598 } // namespace internal | 4613 } // namespace internal |
4599 } // namespace v8 | 4614 } // namespace v8 |
4600 | 4615 |
4601 #endif // V8_TARGET_ARCH_X64 | 4616 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |