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 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 Node* function = | 879 Node* function = |
876 IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); | 880 IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); |
877 Node* function_entry = | 881 Node* function_entry = |
878 Load(MachineType::Pointer(), function, | 882 Load(MachineType::Pointer(), function, |
879 IntPtrConstant(offsetof(Runtime::Function, entry))); | 883 IntPtrConstant(offsetof(Runtime::Function, entry))); |
880 | 884 |
881 return CallStubR(callable.descriptor(), result_size, code_target, context, | 885 return CallStubR(callable.descriptor(), result_size, code_target, context, |
882 arg_count, first_arg, function_entry); | 886 arg_count, first_arg, function_entry); |
883 } | 887 } |
884 | 888 |
885 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { | 889 void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) { |
886 // TODO(rmcilroy): It might be worthwhile to only update the budget for | |
887 // backwards branches. Those are distinguishable by the {JumpLoop} bytecode. | |
888 | |
889 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); | 890 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); |
890 Node* budget_offset = | 891 Node* budget_offset = |
891 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); | 892 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); |
892 | 893 |
893 // Update budget by |weight| and check if it reaches zero. | 894 // Update budget by |weight| and check if it reaches zero. |
894 Variable new_budget(this, MachineRepresentation::kWord32); | 895 Variable new_budget(this, MachineRepresentation::kWord32); |
895 Node* old_budget = | 896 Node* old_budget = |
896 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); | 897 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); |
897 new_budget.Bind(Int32Add(old_budget, weight)); | 898 if (backward) { |
| 899 new_budget.Bind(Int32Sub(old_budget, weight)); |
| 900 } else { |
| 901 new_budget.Bind(Int32Add(old_budget, weight)); |
| 902 } |
898 Node* condition = | 903 Node* condition = |
899 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); | 904 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); |
900 Branch(condition, &ok, &interrupt_check); | 905 Branch(condition, &ok, &interrupt_check); |
901 | 906 |
902 // Perform interrupt and reset budget. | 907 // Perform interrupt and reset budget. |
903 Bind(&interrupt_check); | 908 Bind(&interrupt_check); |
904 { | 909 { |
905 CallRuntime(Runtime::kInterrupt, GetContext()); | 910 CallRuntime(Runtime::kInterrupt, GetContext()); |
906 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); | 911 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); |
907 Goto(&ok); | 912 Goto(&ok); |
908 } | 913 } |
909 | 914 |
910 // Update budget. | 915 // Update budget. |
911 Bind(&ok); | 916 Bind(&ok); |
912 StoreNoWriteBarrier(MachineRepresentation::kWord32, | 917 StoreNoWriteBarrier(MachineRepresentation::kWord32, |
913 BytecodeArrayTaggedPointer(), budget_offset, | 918 BytecodeArrayTaggedPointer(), budget_offset, |
914 new_budget.value()); | 919 new_budget.value()); |
915 } | 920 } |
916 | 921 |
917 Node* InterpreterAssembler::Advance() { | 922 Node* InterpreterAssembler::Advance() { |
918 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); | 923 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); |
919 } | 924 } |
920 | 925 |
921 Node* InterpreterAssembler::Advance(int delta) { | 926 Node* InterpreterAssembler::Advance(int delta) { |
922 return Advance(IntPtrConstant(delta)); | 927 return Advance(IntPtrConstant(delta)); |
923 } | 928 } |
924 | 929 |
925 Node* InterpreterAssembler::Advance(Node* delta) { | 930 Node* InterpreterAssembler::Advance(Node* delta, bool backward) { |
926 if (FLAG_trace_ignition) { | 931 if (FLAG_trace_ignition) { |
927 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 932 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
928 } | 933 } |
929 Node* next_offset = IntPtrAdd(BytecodeOffset(), delta); | 934 Node* next_offset = backward ? IntPtrSub(BytecodeOffset(), delta) |
| 935 : IntPtrAdd(BytecodeOffset(), delta); |
930 bytecode_offset_.Bind(next_offset); | 936 bytecode_offset_.Bind(next_offset); |
931 return next_offset; | 937 return next_offset; |
932 } | 938 } |
933 | 939 |
934 Node* InterpreterAssembler::Jump(Node* delta) { | 940 Node* InterpreterAssembler::Jump(Node* delta, bool backward) { |
935 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); | 941 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); |
936 | 942 |
937 UpdateInterruptBudget(TruncateWordToWord32(delta)); | 943 UpdateInterruptBudget(TruncateWordToWord32(delta), backward); |
938 Node* new_bytecode_offset = Advance(delta); | 944 Node* new_bytecode_offset = Advance(delta, backward); |
939 Node* target_bytecode = LoadBytecode(new_bytecode_offset); | 945 Node* target_bytecode = LoadBytecode(new_bytecode_offset); |
940 return DispatchToBytecode(target_bytecode, new_bytecode_offset); | 946 return DispatchToBytecode(target_bytecode, new_bytecode_offset); |
941 } | 947 } |
942 | 948 |
| 949 Node* InterpreterAssembler::Jump(Node* delta) { return Jump(delta, false); } |
| 950 |
| 951 Node* InterpreterAssembler::JumpBackward(Node* delta) { |
| 952 return Jump(delta, true); |
| 953 } |
| 954 |
943 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 955 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
944 Label match(this), no_match(this); | 956 Label match(this), no_match(this); |
945 | 957 |
946 Branch(condition, &match, &no_match); | 958 Branch(condition, &match, &no_match); |
947 Bind(&match); | 959 Bind(&match); |
948 Jump(delta); | 960 Jump(delta); |
949 Bind(&no_match); | 961 Bind(&no_match); |
950 Dispatch(); | 962 Dispatch(); |
951 } | 963 } |
952 | 964 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 | 1180 |
1169 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { | 1181 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { |
1170 // TODO(rmcilroy): Investigate whether it is worth supporting self | 1182 // TODO(rmcilroy): Investigate whether it is worth supporting self |
1171 // optimization of primitive functions like FullCodegen. | 1183 // optimization of primitive functions like FullCodegen. |
1172 | 1184 |
1173 // Update profiling count by -BytecodeOffset to simulate backedge to start of | 1185 // Update profiling count by -BytecodeOffset to simulate backedge to start of |
1174 // function. | 1186 // function. |
1175 Node* profiling_weight = | 1187 Node* profiling_weight = |
1176 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), | 1188 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), |
1177 TruncateWordToWord32(BytecodeOffset())); | 1189 TruncateWordToWord32(BytecodeOffset())); |
1178 UpdateInterruptBudget(profiling_weight); | 1190 UpdateInterruptBudget(profiling_weight, false); |
1179 } | 1191 } |
1180 | 1192 |
1181 Node* InterpreterAssembler::StackCheckTriggeredInterrupt() { | 1193 Node* InterpreterAssembler::StackCheckTriggeredInterrupt() { |
1182 Node* sp = LoadStackPointer(); | 1194 Node* sp = LoadStackPointer(); |
1183 Node* stack_limit = Load( | 1195 Node* stack_limit = Load( |
1184 MachineType::Pointer(), | 1196 MachineType::Pointer(), |
1185 ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); | 1197 ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); |
1186 return UintPtrLessThan(sp, stack_limit); | 1198 return UintPtrLessThan(sp, stack_limit); |
1187 } | 1199 } |
1188 | 1200 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 Goto(&loop); | 1343 Goto(&loop); |
1332 } | 1344 } |
1333 Bind(&done_loop); | 1345 Bind(&done_loop); |
1334 | 1346 |
1335 return array; | 1347 return array; |
1336 } | 1348 } |
1337 | 1349 |
1338 } // namespace interpreter | 1350 } // namespace interpreter |
1339 } // namespace internal | 1351 } // namespace internal |
1340 } // namespace v8 | 1352 } // namespace v8 |
OLD | NEW |