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 <limits> | 7 #include <limits> |
8 #include <ostream> | 8 #include <ostream> |
9 | 9 |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 } | 388 } |
389 | 389 |
390 Node* InterpreterAssembler::BytecodeOperandUImm(int operand_index) { | 390 Node* InterpreterAssembler::BytecodeOperandUImm(int operand_index) { |
391 DCHECK_EQ(OperandType::kUImm, | 391 DCHECK_EQ(OperandType::kUImm, |
392 Bytecodes::GetOperandType(bytecode_, operand_index)); | 392 Bytecodes::GetOperandType(bytecode_, operand_index)); |
393 OperandSize operand_size = | 393 OperandSize operand_size = |
394 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | 394 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); |
395 return BytecodeUnsignedOperand(operand_index, operand_size); | 395 return BytecodeUnsignedOperand(operand_index, operand_size); |
396 } | 396 } |
397 | 397 |
398 Node* InterpreterAssembler::BytecodeOperandUImmWord(int operand_index) { | |
399 return ChangeUint32ToWord(BytecodeOperandUImm(operand_index)); | |
400 } | |
401 | |
398 Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { | 402 Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { |
399 DCHECK_EQ(OperandType::kImm, | 403 DCHECK_EQ(OperandType::kImm, |
400 Bytecodes::GetOperandType(bytecode_, operand_index)); | 404 Bytecodes::GetOperandType(bytecode_, operand_index)); |
401 OperandSize operand_size = | 405 OperandSize operand_size = |
402 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | 406 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); |
403 return BytecodeSignedOperand(operand_index, operand_size); | 407 return BytecodeSignedOperand(operand_index, operand_size); |
404 } | 408 } |
405 | 409 |
406 Node* InterpreterAssembler::BytecodeOperandImmIntPtr(int operand_index) { | 410 Node* InterpreterAssembler::BytecodeOperandImmIntPtr(int operand_index) { |
407 return ChangeInt32ToIntPtr(BytecodeOperandImm(operand_index)); | 411 return ChangeInt32ToIntPtr(BytecodeOperandImm(operand_index)); |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
848 IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); | 852 IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); |
849 Node* function_entry = | 853 Node* function_entry = |
850 Load(MachineType::Pointer(), function, | 854 Load(MachineType::Pointer(), function, |
851 IntPtrConstant(offsetof(Runtime::Function, entry))); | 855 IntPtrConstant(offsetof(Runtime::Function, entry))); |
852 | 856 |
853 return CallStubR(callable.descriptor(), result_size, code_target, context, | 857 return CallStubR(callable.descriptor(), result_size, code_target, context, |
854 arg_count, first_arg, function_entry); | 858 arg_count, first_arg, function_entry); |
855 } | 859 } |
856 | 860 |
857 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { | 861 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { |
858 // TODO(rmcilroy): It might be worthwhile to only update the budget for | |
859 // backwards branches. Those are distinguishable by the {JumpLoop} bytecode. | |
860 | |
861 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); | 862 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); |
862 Node* budget_offset = | 863 Node* budget_offset = |
863 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); | 864 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); |
864 | 865 |
865 // Update budget by |weight| and check if it reaches zero. | 866 // Update budget by |weight| and check if it reaches zero. |
866 Variable new_budget(this, MachineRepresentation::kWord32); | 867 Variable new_budget(this, MachineRepresentation::kWord32); |
867 Node* old_budget = | 868 Node* old_budget = |
868 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); | 869 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); |
869 new_budget.Bind(Int32Add(old_budget, weight)); | 870 new_budget.Bind(Int32Sub(old_budget, weight)); |
870 Node* condition = | 871 Node* condition = |
871 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); | 872 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); |
872 Branch(condition, &ok, &interrupt_check); | 873 Branch(condition, &ok, &interrupt_check); |
873 | 874 |
874 // Perform interrupt and reset budget. | 875 // Perform interrupt and reset budget. |
875 Bind(&interrupt_check); | 876 Bind(&interrupt_check); |
876 { | 877 { |
877 CallRuntime(Runtime::kInterrupt, GetContext()); | 878 CallRuntime(Runtime::kInterrupt, GetContext()); |
878 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); | 879 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); |
879 Goto(&ok); | 880 Goto(&ok); |
880 } | 881 } |
881 | 882 |
882 // Update budget. | 883 // Update budget. |
883 Bind(&ok); | 884 Bind(&ok); |
884 StoreNoWriteBarrier(MachineRepresentation::kWord32, | 885 StoreNoWriteBarrier(MachineRepresentation::kWord32, |
885 BytecodeArrayTaggedPointer(), budget_offset, | 886 BytecodeArrayTaggedPointer(), budget_offset, |
886 new_budget.value()); | 887 new_budget.value()); |
887 } | 888 } |
888 | 889 |
889 Node* InterpreterAssembler::Advance() { | 890 Node* InterpreterAssembler::Advance() { |
890 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); | 891 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); |
891 } | 892 } |
892 | 893 |
893 Node* InterpreterAssembler::Advance(int delta) { | 894 Node* InterpreterAssembler::Advance(int delta) { |
894 return Advance(IntPtrConstant(delta)); | 895 return Advance(IntPtrConstant(delta)); |
895 } | 896 } |
896 | 897 |
897 Node* InterpreterAssembler::Advance(Node* delta) { | 898 Node* InterpreterAssembler::Advance(Node* delta, bool reverse) { |
898 if (FLAG_trace_ignition) { | 899 if (FLAG_trace_ignition) { |
899 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 900 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
900 } | 901 } |
901 Node* next_offset = IntPtrAdd(BytecodeOffset(), delta); | 902 Node* next_offset = reverse ? IntPtrSub(BytecodeOffset(), delta) |
903 : IntPtrAdd(BytecodeOffset(), delta); | |
902 bytecode_offset_.Bind(next_offset); | 904 bytecode_offset_.Bind(next_offset); |
903 return next_offset; | 905 return next_offset; |
904 } | 906 } |
905 | 907 |
906 Node* InterpreterAssembler::Jump(Node* delta) { | 908 Node* InterpreterAssembler::Jump(Node* delta, bool reverse) { |
907 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); | 909 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); |
908 | 910 |
909 UpdateInterruptBudget(TruncateWordToWord32(delta)); | 911 if (reverse) { |
rmcilroy
2017/01/17 17:58:38
Could this be done separately (or maybe not at all
Leszek Swirski
2017/01/18 17:22:28
Sure, added a "reverse" flag same as for advance.
| |
910 Node* new_bytecode_offset = Advance(delta); | 912 UpdateInterruptBudget(TruncateWordToWord32(delta)); |
913 } | |
914 Node* new_bytecode_offset = Advance(delta, reverse); | |
911 Node* target_bytecode = LoadBytecode(new_bytecode_offset); | 915 Node* target_bytecode = LoadBytecode(new_bytecode_offset); |
912 return DispatchToBytecode(target_bytecode, new_bytecode_offset); | 916 return DispatchToBytecode(target_bytecode, new_bytecode_offset); |
913 } | 917 } |
914 | 918 |
915 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 919 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
916 Label match(this), no_match(this); | 920 Label match(this), no_match(this); |
917 | 921 |
918 Branch(condition, &match, &no_match); | 922 Branch(condition, &match, &no_match); |
919 Bind(&match); | 923 Bind(&match); |
920 Jump(delta); | 924 Jump(delta); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1303 Goto(&loop); | 1307 Goto(&loop); |
1304 } | 1308 } |
1305 Bind(&done_loop); | 1309 Bind(&done_loop); |
1306 | 1310 |
1307 return array; | 1311 return array; |
1308 } | 1312 } |
1309 | 1313 |
1310 } // namespace interpreter | 1314 } // namespace interpreter |
1311 } // namespace internal | 1315 } // namespace internal |
1312 } // namespace v8 | 1316 } // namespace v8 |
OLD | NEW |