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 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 Node* function = | 851 Node* function = |
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, bool backwards) { |
858 // TODO(rmcilroy): It might be worthwhile to only update the budget for | 862 // TODO(rmcilroy): It might be worthwhile to only update the budget for |
859 // backwards branches. Those are distinguishable by the {JumpLoop} bytecode. | 863 // backwards branches. Those are distinguishable by the {JumpLoop} bytecode. |
860 | 864 |
861 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); | 865 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); |
862 Node* budget_offset = | 866 Node* budget_offset = |
863 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); | 867 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); |
864 | 868 |
865 // Update budget by |weight| and check if it reaches zero. | 869 // Update budget by |weight| and check if it reaches zero. |
866 Variable new_budget(this, MachineRepresentation::kWord32); | 870 Variable new_budget(this, MachineRepresentation::kWord32); |
867 Node* old_budget = | 871 Node* old_budget = |
868 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); | 872 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); |
869 new_budget.Bind(Int32Add(old_budget, weight)); | 873 if (backwards) { |
| 874 new_budget.Bind(Int32Sub(old_budget, weight)); |
| 875 } else { |
| 876 new_budget.Bind(Int32Add(old_budget, weight)); |
| 877 } |
870 Node* condition = | 878 Node* condition = |
871 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); | 879 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); |
872 Branch(condition, &ok, &interrupt_check); | 880 Branch(condition, &ok, &interrupt_check); |
873 | 881 |
874 // Perform interrupt and reset budget. | 882 // Perform interrupt and reset budget. |
875 Bind(&interrupt_check); | 883 Bind(&interrupt_check); |
876 { | 884 { |
877 CallRuntime(Runtime::kInterrupt, GetContext()); | 885 CallRuntime(Runtime::kInterrupt, GetContext()); |
878 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); | 886 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); |
879 Goto(&ok); | 887 Goto(&ok); |
880 } | 888 } |
881 | 889 |
882 // Update budget. | 890 // Update budget. |
883 Bind(&ok); | 891 Bind(&ok); |
884 StoreNoWriteBarrier(MachineRepresentation::kWord32, | 892 StoreNoWriteBarrier(MachineRepresentation::kWord32, |
885 BytecodeArrayTaggedPointer(), budget_offset, | 893 BytecodeArrayTaggedPointer(), budget_offset, |
886 new_budget.value()); | 894 new_budget.value()); |
887 } | 895 } |
888 | 896 |
889 Node* InterpreterAssembler::Advance() { | 897 Node* InterpreterAssembler::Advance() { |
890 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); | 898 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); |
891 } | 899 } |
892 | 900 |
893 Node* InterpreterAssembler::Advance(int delta) { | 901 Node* InterpreterAssembler::Advance(int delta) { |
894 return Advance(IntPtrConstant(delta)); | 902 return Advance(IntPtrConstant(delta)); |
895 } | 903 } |
896 | 904 |
897 Node* InterpreterAssembler::Advance(Node* delta) { | 905 Node* InterpreterAssembler::Advance(Node* delta, bool backwards) { |
898 if (FLAG_trace_ignition) { | 906 if (FLAG_trace_ignition) { |
899 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 907 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
900 } | 908 } |
901 Node* next_offset = IntPtrAdd(BytecodeOffset(), delta); | 909 Node* next_offset = backwards ? IntPtrSub(BytecodeOffset(), delta) |
| 910 : IntPtrAdd(BytecodeOffset(), delta); |
902 bytecode_offset_.Bind(next_offset); | 911 bytecode_offset_.Bind(next_offset); |
903 return next_offset; | 912 return next_offset; |
904 } | 913 } |
905 | 914 |
906 Node* InterpreterAssembler::Jump(Node* delta) { | 915 Node* InterpreterAssembler::Jump(Node* delta, bool backwards) { |
907 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); | 916 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); |
908 | 917 |
909 UpdateInterruptBudget(TruncateWordToWord32(delta)); | 918 UpdateInterruptBudget(TruncateWordToWord32(delta), backwards); |
910 Node* new_bytecode_offset = Advance(delta); | 919 Node* new_bytecode_offset = Advance(delta, backwards); |
911 Node* target_bytecode = LoadBytecode(new_bytecode_offset); | 920 Node* target_bytecode = LoadBytecode(new_bytecode_offset); |
912 return DispatchToBytecode(target_bytecode, new_bytecode_offset); | 921 return DispatchToBytecode(target_bytecode, new_bytecode_offset); |
913 } | 922 } |
914 | 923 |
915 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 924 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
916 Label match(this), no_match(this); | 925 Label match(this), no_match(this); |
917 | 926 |
918 Branch(condition, &match, &no_match); | 927 Branch(condition, &match, &no_match); |
919 Bind(&match); | 928 Bind(&match); |
920 Jump(delta); | 929 Jump(delta); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 | 1149 |
1141 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { | 1150 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { |
1142 // TODO(rmcilroy): Investigate whether it is worth supporting self | 1151 // TODO(rmcilroy): Investigate whether it is worth supporting self |
1143 // optimization of primitive functions like FullCodegen. | 1152 // optimization of primitive functions like FullCodegen. |
1144 | 1153 |
1145 // Update profiling count by -BytecodeOffset to simulate backedge to start of | 1154 // Update profiling count by -BytecodeOffset to simulate backedge to start of |
1146 // function. | 1155 // function. |
1147 Node* profiling_weight = | 1156 Node* profiling_weight = |
1148 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), | 1157 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), |
1149 TruncateWordToWord32(BytecodeOffset())); | 1158 TruncateWordToWord32(BytecodeOffset())); |
1150 UpdateInterruptBudget(profiling_weight); | 1159 UpdateInterruptBudget(profiling_weight, false); |
1151 } | 1160 } |
1152 | 1161 |
1153 Node* InterpreterAssembler::StackCheckTriggeredInterrupt() { | 1162 Node* InterpreterAssembler::StackCheckTriggeredInterrupt() { |
1154 Node* sp = LoadStackPointer(); | 1163 Node* sp = LoadStackPointer(); |
1155 Node* stack_limit = Load( | 1164 Node* stack_limit = Load( |
1156 MachineType::Pointer(), | 1165 MachineType::Pointer(), |
1157 ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); | 1166 ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); |
1158 return UintPtrLessThan(sp, stack_limit); | 1167 return UintPtrLessThan(sp, stack_limit); |
1159 } | 1168 } |
1160 | 1169 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 Goto(&loop); | 1312 Goto(&loop); |
1304 } | 1313 } |
1305 Bind(&done_loop); | 1314 Bind(&done_loop); |
1306 | 1315 |
1307 return array; | 1316 return array; |
1308 } | 1317 } |
1309 | 1318 |
1310 } // namespace interpreter | 1319 } // namespace interpreter |
1311 } // namespace internal | 1320 } // namespace internal |
1312 } // namespace v8 | 1321 } // namespace v8 |
OLD | NEW |