| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { | 321 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { |
| 322 __ Mov(x2, Operand(profiling_counter_)); | 322 __ Mov(x2, Operand(profiling_counter_)); |
| 323 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset)); | 323 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset)); |
| 324 __ Subs(x3, x3, Operand(Smi::FromInt(delta))); | 324 __ Subs(x3, x3, Operand(Smi::FromInt(delta))); |
| 325 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); | 325 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); |
| 326 } | 326 } |
| 327 | 327 |
| 328 | 328 |
| 329 void FullCodeGenerator::EmitProfilingCounterReset() { | 329 void FullCodeGenerator::EmitProfilingCounterReset() { |
| 330 int reset_value = FLAG_interrupt_budget; | 330 int reset_value = FLAG_interrupt_budget; |
| 331 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { | |
| 332 // Self-optimization is a one-off thing. if it fails, don't try again. | |
| 333 reset_value = Smi::kMaxValue; | |
| 334 } | |
| 335 if (isolate()->IsDebuggerActive()) { | 331 if (isolate()->IsDebuggerActive()) { |
| 336 // Detect debug break requests as soon as possible. | 332 // Detect debug break requests as soon as possible. |
| 337 reset_value = FLAG_interrupt_budget >> 4; | 333 reset_value = FLAG_interrupt_budget >> 4; |
| 338 } | 334 } |
| 339 __ Mov(x2, Operand(profiling_counter_)); | 335 __ Mov(x2, Operand(profiling_counter_)); |
| 340 __ Mov(x3, Operand(Smi::FromInt(reset_value))); | 336 __ Mov(x3, Operand(Smi::FromInt(reset_value))); |
| 341 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); | 337 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); |
| 342 } | 338 } |
| 343 | 339 |
| 344 | 340 |
| 345 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, | 341 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, |
| 346 Label* back_edge_target) { | 342 Label* back_edge_target) { |
| 347 ASSERT(jssp.Is(__ StackPointer())); | 343 ASSERT(jssp.Is(__ StackPointer())); |
| 348 Comment cmnt(masm_, "[ Back edge bookkeeping"); | 344 Comment cmnt(masm_, "[ Back edge bookkeeping"); |
| 349 // Block literal pools whilst emitting back edge code. | 345 // Block literal pools whilst emitting back edge code. |
| 350 Assembler::BlockConstPoolScope block_const_pool(masm_); | 346 Assembler::BlockConstPoolScope block_const_pool(masm_); |
| 351 Label ok; | 347 Label ok; |
| 352 | 348 |
| 353 int weight = 1; | 349 ASSERT(back_edge_target->is_bound()); |
| 354 if (FLAG_weighted_back_edges) { | 350 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); |
| 355 ASSERT(back_edge_target->is_bound()); | 351 int weight = Min(kMaxBackEdgeWeight, |
| 356 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); | 352 Max(1, distance / kCodeSizeMultiplier)); |
| 357 weight = Min(kMaxBackEdgeWeight, | |
| 358 Max(1, distance / kCodeSizeMultiplier)); | |
| 359 } | |
| 360 EmitProfilingCounterDecrement(weight); | 353 EmitProfilingCounterDecrement(weight); |
| 361 __ B(pl, &ok); | 354 __ B(pl, &ok); |
| 362 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); | 355 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); |
| 363 | 356 |
| 364 // Record a mapping of this PC offset to the OSR id. This is used to find | 357 // Record a mapping of this PC offset to the OSR id. This is used to find |
| 365 // the AST id from the unoptimized code in order to use it as a key into | 358 // the AST id from the unoptimized code in order to use it as a key into |
| 366 // the deoptimization input data found in the optimized code. | 359 // the deoptimization input data found in the optimized code. |
| 367 RecordBackEdge(stmt->OsrEntryId()); | 360 RecordBackEdge(stmt->OsrEntryId()); |
| 368 | 361 |
| 369 EmitProfilingCounterReset(); | 362 EmitProfilingCounterReset(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 385 | 378 |
| 386 } else { | 379 } else { |
| 387 __ Bind(&return_label_); | 380 __ Bind(&return_label_); |
| 388 if (FLAG_trace) { | 381 if (FLAG_trace) { |
| 389 // Push the return value on the stack as the parameter. | 382 // Push the return value on the stack as the parameter. |
| 390 // Runtime::TraceExit returns its parameter in x0. | 383 // Runtime::TraceExit returns its parameter in x0. |
| 391 __ Push(result_register()); | 384 __ Push(result_register()); |
| 392 __ CallRuntime(Runtime::kTraceExit, 1); | 385 __ CallRuntime(Runtime::kTraceExit, 1); |
| 393 ASSERT(x0.Is(result_register())); | 386 ASSERT(x0.Is(result_register())); |
| 394 } | 387 } |
| 395 if (FLAG_interrupt_at_exit || FLAG_self_optimization) { | 388 // Pretend that the exit is a backwards jump to the entry. |
| 396 // Pretend that the exit is a backwards jump to the entry. | 389 int weight = 1; |
| 397 int weight = 1; | 390 if (info_->ShouldSelfOptimize()) { |
| 398 if (info_->ShouldSelfOptimize()) { | 391 weight = FLAG_interrupt_budget / FLAG_self_opt_count; |
| 399 weight = FLAG_interrupt_budget / FLAG_self_opt_count; | 392 } else { |
| 400 } else if (FLAG_weighted_back_edges) { | 393 int distance = masm_->pc_offset(); |
| 401 int distance = masm_->pc_offset(); | 394 weight = Min(kMaxBackEdgeWeight, |
| 402 weight = Min(kMaxBackEdgeWeight, | 395 Max(1, distance / kCodeSizeMultiplier)); |
| 403 Max(1, distance / kCodeSizeMultiplier)); | |
| 404 } | |
| 405 EmitProfilingCounterDecrement(weight); | |
| 406 Label ok; | |
| 407 __ B(pl, &ok); | |
| 408 __ Push(x0); | |
| 409 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) { | |
| 410 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | |
| 411 __ Push(x10); | |
| 412 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1); | |
| 413 } else { | |
| 414 __ Call(isolate()->builtins()->InterruptCheck(), | |
| 415 RelocInfo::CODE_TARGET); | |
| 416 } | |
| 417 __ Pop(x0); | |
| 418 EmitProfilingCounterReset(); | |
| 419 __ Bind(&ok); | |
| 420 } | 396 } |
| 397 EmitProfilingCounterDecrement(weight); |
| 398 Label ok; |
| 399 __ B(pl, &ok); |
| 400 __ Push(x0); |
| 401 __ Call(isolate()->builtins()->InterruptCheck(), |
| 402 RelocInfo::CODE_TARGET); |
| 403 __ Pop(x0); |
| 404 EmitProfilingCounterReset(); |
| 405 __ Bind(&ok); |
| 421 | 406 |
| 422 // Make sure that the constant pool is not emitted inside of the return | 407 // Make sure that the constant pool is not emitted inside of the return |
| 423 // sequence. This sequence can get patched when the debugger is used. See | 408 // sequence. This sequence can get patched when the debugger is used. See |
| 424 // debug-a64.cc:BreakLocationIterator::SetDebugBreakAtReturn(). | 409 // debug-a64.cc:BreakLocationIterator::SetDebugBreakAtReturn(). |
| 425 { | 410 { |
| 426 InstructionAccurateScope scope(masm_, | 411 InstructionAccurateScope scope(masm_, |
| 427 Assembler::kJSRetSequenceInstructions); | 412 Assembler::kJSRetSequenceInstructions); |
| 428 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 413 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); |
| 429 __ RecordJSReturn(); | 414 __ RecordJSReturn(); |
| 430 // This code is generated using Assembler methods rather than Macro | 415 // This code is generated using Assembler methods rather than Macro |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 __ B(clause->body_target()); | 1024 __ B(clause->body_target()); |
| 1040 __ Bind(&slow_case); | 1025 __ Bind(&slow_case); |
| 1041 } | 1026 } |
| 1042 | 1027 |
| 1043 // Record position before stub call for type feedback. | 1028 // Record position before stub call for type feedback. |
| 1044 SetSourcePosition(clause->position()); | 1029 SetSourcePosition(clause->position()); |
| 1045 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1030 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 1046 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1031 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
| 1047 patch_site.EmitPatchInfo(); | 1032 patch_site.EmitPatchInfo(); |
| 1048 | 1033 |
| 1034 Label skip; |
| 1035 __ B(&skip); |
| 1036 PrepareForBailout(clause, TOS_REG); |
| 1037 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); |
| 1038 __ Drop(1); |
| 1039 __ B(clause->body_target()); |
| 1040 __ Bind(&skip); |
| 1041 |
| 1049 __ Cbnz(x0, &next_test); | 1042 __ Cbnz(x0, &next_test); |
| 1050 __ Drop(1); // Switch value is no longer needed. | 1043 __ Drop(1); // Switch value is no longer needed. |
| 1051 __ B(clause->body_target()); | 1044 __ B(clause->body_target()); |
| 1052 } | 1045 } |
| 1053 | 1046 |
| 1054 // Discard the test value and jump to the default if present, otherwise to | 1047 // Discard the test value and jump to the default if present, otherwise to |
| 1055 // the end of the statement. | 1048 // the end of the statement. |
| 1056 __ Bind(&next_test); | 1049 __ Bind(&next_test); |
| 1057 __ Drop(1); // Switch value is no longer needed. | 1050 __ Drop(1); // Switch value is no longer needed. |
| 1058 if (default_clause == NULL) { | 1051 if (default_clause == NULL) { |
| (...skipping 2415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3474 VisitForStackValue(args->at(0)); | 3467 VisitForStackValue(args->at(0)); |
| 3475 VisitForStackValue(args->at(1)); | 3468 VisitForStackValue(args->at(1)); |
| 3476 | 3469 |
| 3477 StringCompareStub stub; | 3470 StringCompareStub stub; |
| 3478 __ CallStub(&stub); | 3471 __ CallStub(&stub); |
| 3479 context()->Plug(x0); | 3472 context()->Plug(x0); |
| 3480 } | 3473 } |
| 3481 | 3474 |
| 3482 | 3475 |
| 3483 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { | 3476 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { |
| 3484 // Load the argument on the stack and call the stub. | 3477 // Load the argument on the stack and call the runtime function. |
| 3485 TranscendentalCacheStub stub(TranscendentalCache::LOG, | |
| 3486 TranscendentalCacheStub::TAGGED); | |
| 3487 ZoneList<Expression*>* args = expr->arguments(); | 3478 ZoneList<Expression*>* args = expr->arguments(); |
| 3488 ASSERT(args->length() == 1); | 3479 ASSERT(args->length() == 1); |
| 3489 VisitForStackValue(args->at(0)); | 3480 VisitForStackValue(args->at(0)); |
| 3490 __ CallStub(&stub); | 3481 __ CallRuntime(Runtime::kMath_log, 1); |
| 3491 context()->Plug(x0); | 3482 context()->Plug(x0); |
| 3492 } | 3483 } |
| 3493 | 3484 |
| 3494 | 3485 |
| 3495 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { | 3486 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { |
| 3496 // Load the argument on the stack and call the runtime function. | 3487 // Load the argument on the stack and call the runtime function. |
| 3497 ZoneList<Expression*>* args = expr->arguments(); | 3488 ZoneList<Expression*>* args = expr->arguments(); |
| 3498 ASSERT(args->length() == 1); | 3489 ASSERT(args->length() == 1); |
| 3499 VisitForStackValue(args->at(0)); | 3490 VisitForStackValue(args->at(0)); |
| 3500 __ CallRuntime(Runtime::kMath_sqrt, 1); | 3491 __ CallRuntime(Runtime::kMath_sqrt, 1); |
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5034 return previous_; | 5025 return previous_; |
| 5035 } | 5026 } |
| 5036 | 5027 |
| 5037 | 5028 |
| 5038 #undef __ | 5029 #undef __ |
| 5039 | 5030 |
| 5040 | 5031 |
| 5041 } } // namespace v8::internal | 5032 } } // namespace v8::internal |
| 5042 | 5033 |
| 5043 #endif // V8_TARGET_ARCH_A64 | 5034 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |