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 |