| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 #include "src/interpreter/interpreter-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/frames.h" | 10 #include "src/frames.h" |
| 11 #include "src/interface-descriptors.h" | 11 #include "src/interface-descriptors.h" |
| 12 #include "src/interpreter/bytecodes.h" | 12 #include "src/interpreter/bytecodes.h" |
| 13 #include "src/interpreter/interpreter.h" |
| 13 #include "src/machine-type.h" | 14 #include "src/machine-type.h" |
| 14 #include "src/macro-assembler.h" | 15 #include "src/macro-assembler.h" |
| 15 #include "src/zone.h" | 16 #include "src/zone.h" |
| 16 | 17 |
| 17 namespace v8 { | 18 namespace v8 { |
| 18 namespace internal { | 19 namespace internal { |
| 19 namespace interpreter { | 20 namespace interpreter { |
| 20 | 21 |
| 21 using compiler::Node; | 22 using compiler::Node; |
| 22 | 23 |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); | 367 Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); |
| 367 Node* function = IntPtrAdd(function_table, function_offset); | 368 Node* function = IntPtrAdd(function_table, function_offset); |
| 368 Node* function_entry = | 369 Node* function_entry = |
| 369 Load(MachineType::Pointer(), function, | 370 Load(MachineType::Pointer(), function, |
| 370 Int32Constant(offsetof(Runtime::Function, entry))); | 371 Int32Constant(offsetof(Runtime::Function, entry))); |
| 371 | 372 |
| 372 return CallStub(callable.descriptor(), code_target, context, arg_count, | 373 return CallStub(callable.descriptor(), code_target, context, arg_count, |
| 373 first_arg, function_entry, result_size); | 374 first_arg, function_entry, result_size); |
| 374 } | 375 } |
| 375 | 376 |
| 377 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { |
| 378 CodeStubAssembler::Label ok(this); |
| 379 CodeStubAssembler::Label interrupt_check(this); |
| 380 CodeStubAssembler::Label end(this); |
| 381 Node* budget_offset = |
| 382 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); |
| 383 |
| 384 // Update budget by |weight| and check if it reaches zero. |
| 385 Node* old_budget = |
| 386 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); |
| 387 Node* new_budget = Int32Add(old_budget, weight); |
| 388 Node* condition = Int32GreaterThanOrEqual(new_budget, Int32Constant(0)); |
| 389 Branch(condition, &ok, &interrupt_check); |
| 390 |
| 391 // Perform interrupt and reset budget. |
| 392 Bind(&interrupt_check); |
| 393 CallRuntime(Runtime::kInterrupt, GetContext()); |
| 394 StoreNoWriteBarrier(MachineRepresentation::kWord32, |
| 395 BytecodeArrayTaggedPointer(), budget_offset, |
| 396 Int32Constant(Interpreter::InterruptBudget())); |
| 397 Goto(&end); |
| 398 |
| 399 // Update budget. |
| 400 Bind(&ok); |
| 401 StoreNoWriteBarrier(MachineRepresentation::kWord32, |
| 402 BytecodeArrayTaggedPointer(), budget_offset, new_budget); |
| 403 Goto(&end); |
| 404 Bind(&end); |
| 405 } |
| 406 |
| 376 Node* InterpreterAssembler::Advance(int delta) { | 407 Node* InterpreterAssembler::Advance(int delta) { |
| 377 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); | 408 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); |
| 378 } | 409 } |
| 379 | 410 |
| 380 Node* InterpreterAssembler::Advance(Node* delta) { | 411 Node* InterpreterAssembler::Advance(Node* delta) { |
| 381 return IntPtrAdd(BytecodeOffset(), delta); | 412 return IntPtrAdd(BytecodeOffset(), delta); |
| 382 } | 413 } |
| 383 | 414 |
| 384 void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); } | 415 void InterpreterAssembler::Jump(Node* delta) { |
| 416 UpdateInterruptBudget(delta); |
| 417 DispatchTo(Advance(delta)); |
| 418 } |
| 385 | 419 |
| 386 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 420 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
| 387 CodeStubAssembler::Label match(this); | 421 CodeStubAssembler::Label match(this); |
| 388 CodeStubAssembler::Label no_match(this); | 422 CodeStubAssembler::Label no_match(this); |
| 389 | 423 |
| 390 Branch(condition, &match, &no_match); | 424 Branch(condition, &match, &no_match); |
| 391 Bind(&match); | 425 Bind(&match); |
| 392 DispatchTo(Advance(delta)); | 426 Jump(delta); |
| 393 Bind(&no_match); | 427 Bind(&no_match); |
| 394 Dispatch(); | 428 Dispatch(); |
| 395 } | 429 } |
| 396 | 430 |
| 397 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 431 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
| 398 JumpConditional(WordEqual(lhs, rhs), delta); | 432 JumpConditional(WordEqual(lhs, rhs), delta); |
| 399 } | 433 } |
| 400 | 434 |
| 401 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, | 435 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, |
| 402 Node* delta) { | 436 Node* delta) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 424 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), | 458 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), |
| 425 new_bytecode_offset, BytecodeArrayTaggedPointer(), | 459 new_bytecode_offset, BytecodeArrayTaggedPointer(), |
| 426 DispatchTableRawPointer(), GetContext()}; | 460 DispatchTableRawPointer(), GetContext()}; |
| 427 TailCall(descriptor, target_code_object, args, 0); | 461 TailCall(descriptor, target_code_object, args, 0); |
| 428 } | 462 } |
| 429 | 463 |
| 430 void InterpreterAssembler::InterpreterReturn() { | 464 void InterpreterAssembler::InterpreterReturn() { |
| 431 if (FLAG_trace_ignition) { | 465 if (FLAG_trace_ignition) { |
| 432 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 466 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
| 433 } | 467 } |
| 468 |
| 469 // TODO(rmcilroy): Investigate whether it is worth supporting self |
| 470 // optimization of primitive functions like FullCodegen. |
| 471 |
| 472 // Update profiling count by -BytecodeOffset to simulate backedge to start of |
| 473 // function. |
| 474 Node* profiling_weight = |
| 475 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), |
| 476 BytecodeOffset()); |
| 477 UpdateInterruptBudget(profiling_weight); |
| 478 |
| 434 InterpreterDispatchDescriptor descriptor(isolate()); | 479 InterpreterDispatchDescriptor descriptor(isolate()); |
| 435 Node* exit_trampoline_code_object = | 480 Node* exit_trampoline_code_object = |
| 436 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 481 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); |
| 437 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), | 482 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), |
| 438 BytecodeOffset(), BytecodeArrayTaggedPointer(), | 483 BytecodeOffset(), BytecodeArrayTaggedPointer(), |
| 439 DispatchTableRawPointer(), GetContext()}; | 484 DispatchTableRawPointer(), GetContext()}; |
| 440 TailCall(descriptor, exit_trampoline_code_object, args, 0); | 485 TailCall(descriptor, exit_trampoline_code_object, args, 0); |
| 441 } | 486 } |
| 442 | 487 |
| 443 void InterpreterAssembler::StackCheck() { | 488 void InterpreterAssembler::StackCheck() { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 | 539 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 |
| 495 return true; | 540 return true; |
| 496 #else | 541 #else |
| 497 #error "Unknown Architecture" | 542 #error "Unknown Architecture" |
| 498 #endif | 543 #endif |
| 499 } | 544 } |
| 500 | 545 |
| 501 } // namespace interpreter | 546 } // namespace interpreter |
| 502 } // namespace internal | 547 } // namespace internal |
| 503 } // namespace v8 | 548 } // namespace v8 |
| OLD | NEW |