| 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 |