Chromium Code Reviews| 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/interpreter/interpreter.h" |
| 14 #include "src/machine-type.h" | 14 #include "src/machine-type.h" |
| 15 #include "src/macro-assembler.h" | 15 #include "src/macro-assembler.h" |
| 16 #include "src/zone.h" | 16 #include "src/zone.h" |
| 17 | 17 |
| 18 namespace v8 { | 18 namespace v8 { |
| 19 namespace internal { | 19 namespace internal { |
| 20 namespace interpreter { | 20 namespace interpreter { |
| 21 | 21 |
| 22 using compiler::Node; | 22 using compiler::Node; |
| 23 | 23 |
| 24 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 24 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
| 25 Bytecode bytecode) | 25 Bytecode bytecode, |
| 26 OperandScale operand_scale) | |
| 26 : compiler::CodeStubAssembler(isolate, zone, | 27 : compiler::CodeStubAssembler(isolate, zone, |
| 27 InterpreterDispatchDescriptor(isolate), | 28 InterpreterDispatchDescriptor(isolate), |
| 28 Code::ComputeFlags(Code::BYTECODE_HANDLER), | 29 Code::ComputeFlags(Code::BYTECODE_HANDLER), |
| 29 Bytecodes::ToString(bytecode), 0), | 30 Bytecodes::ToString(bytecode), 0), |
| 30 bytecode_(bytecode), | 31 bytecode_(bytecode), |
| 32 operand_scale_(operand_scale), | |
| 31 accumulator_(this, MachineRepresentation::kTagged), | 33 accumulator_(this, MachineRepresentation::kTagged), |
| 32 context_(this, MachineRepresentation::kTagged), | 34 context_(this, MachineRepresentation::kTagged), |
| 33 bytecode_array_(this, MachineRepresentation::kTagged), | 35 bytecode_array_(this, MachineRepresentation::kTagged), |
| 34 disable_stack_check_across_call_(false), | 36 disable_stack_check_across_call_(false), |
| 35 stack_pointer_before_call_(nullptr) { | 37 stack_pointer_before_call_(nullptr) { |
| 36 accumulator_.Bind( | 38 accumulator_.Bind( |
| 37 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); | 39 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); |
| 38 context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter)); | 40 context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter)); |
| 39 bytecode_array_.Bind( | 41 bytecode_array_.Bind( |
| 40 Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter)); | 42 Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 79 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |
| 78 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 80 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |
| 79 } | 81 } |
| 80 | 82 |
| 81 Node* InterpreterAssembler::LoadRegister(int offset) { | 83 Node* InterpreterAssembler::LoadRegister(int offset) { |
| 82 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), | 84 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), |
| 83 IntPtrConstant(offset)); | 85 IntPtrConstant(offset)); |
| 84 } | 86 } |
| 85 | 87 |
| 86 Node* InterpreterAssembler::LoadRegister(Register reg) { | 88 Node* InterpreterAssembler::LoadRegister(Register reg) { |
| 87 return LoadRegister(reg.ToOperand() << kPointerSizeLog2); | 89 return LoadRegister(IntPtrConstant(-reg.index())); |
| 88 } | 90 } |
| 89 | 91 |
| 90 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 92 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { |
| 91 return WordShl(index, kPointerSizeLog2); | 93 return WordShl(index, kPointerSizeLog2); |
| 92 } | 94 } |
| 93 | 95 |
| 94 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 96 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { |
| 95 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), | 97 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), |
| 96 RegisterFrameOffset(reg_index)); | 98 RegisterFrameOffset(reg_index)); |
| 97 } | 99 } |
| 98 | 100 |
| 99 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { | 101 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { |
| 100 return StoreNoWriteBarrier(MachineRepresentation::kTagged, | 102 return StoreNoWriteBarrier(MachineRepresentation::kTagged, |
| 101 RegisterFileRawPointer(), IntPtrConstant(offset), | 103 RegisterFileRawPointer(), IntPtrConstant(offset), |
| 102 value); | 104 value); |
| 103 } | 105 } |
| 104 | 106 |
| 105 Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) { | 107 Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) { |
| 106 return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); | 108 return StoreRegister(value, IntPtrConstant(-reg.index())); |
| 107 } | 109 } |
| 108 | 110 |
| 109 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 111 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { |
| 110 return StoreNoWriteBarrier(MachineRepresentation::kTagged, | 112 return StoreNoWriteBarrier(MachineRepresentation::kTagged, |
| 111 RegisterFileRawPointer(), | 113 RegisterFileRawPointer(), |
| 112 RegisterFrameOffset(reg_index), value); | 114 RegisterFrameOffset(reg_index), value); |
| 113 } | 115 } |
| 114 | 116 |
| 115 Node* InterpreterAssembler::NextRegister(Node* reg_index) { | 117 Node* InterpreterAssembler::NextRegister(Node* reg_index) { |
| 116 // Register indexes are negative, so the next index is minus one. | 118 // Register indexes are negative, so the next index is minus one. |
| 117 return IntPtrAdd(reg_index, IntPtrConstant(-1)); | 119 return IntPtrAdd(reg_index, IntPtrConstant(-1)); |
| 118 } | 120 } |
| 119 | 121 |
| 120 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 122 Node* InterpreterAssembler::OperandOffset(int operand_index) { |
| 121 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | 123 return IntPtrConstant( |
| 122 DCHECK_EQ(OperandSize::kByte, | 124 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale())); |
| 123 Bytecodes::GetOperandSize(bytecode_, operand_index)); | |
| 124 return Load( | |
| 125 MachineType::Uint8(), BytecodeArrayTaggedPointer(), | |
| 126 IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset( | |
| 127 bytecode_, operand_index)))); | |
| 128 } | 125 } |
| 129 | 126 |
| 130 Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) { | 127 Node* InterpreterAssembler::BytecodeOperandUnsignedByte(int operand_index) { |
| 131 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | 128 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); |
| 132 DCHECK_EQ(OperandSize::kByte, | 129 DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( |
| 133 Bytecodes::GetOperandSize(bytecode_, operand_index)); | 130 bytecode_, operand_index, operand_scale())); |
| 134 Node* load = Load( | 131 Node* operand_offset = OperandOffset(operand_index); |
| 135 MachineType::Int8(), BytecodeArrayTaggedPointer(), | 132 return Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), |
| 136 IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset( | 133 IntPtrAdd(BytecodeOffset(), operand_offset)); |
| 137 bytecode_, operand_index)))); | 134 } |
| 135 | |
| 136 Node* InterpreterAssembler::BytecodeOperandSignedByte(int operand_index) { | |
| 137 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | |
| 138 DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( | |
| 139 bytecode_, operand_index, operand_scale())); | |
| 140 Node* operand_offset = OperandOffset(operand_index); | |
| 141 Node* load = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(), | |
| 142 IntPtrAdd(BytecodeOffset(), operand_offset)); | |
| 143 | |
| 138 // Ensure that we sign extend to full pointer size | 144 // Ensure that we sign extend to full pointer size |
| 139 if (kPointerSize == 8) { | 145 if (kPointerSize == 8) { |
| 140 load = ChangeInt32ToInt64(load); | 146 load = ChangeInt32ToInt64(load); |
| 141 } | 147 } |
| 142 return load; | 148 return load; |
| 143 } | 149 } |
| 144 | 150 |
| 145 Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { | 151 compiler::Node* InterpreterAssembler::BytecodeReadUnalignedBytes( |
|
rmcilroy
2016/03/21 12:41:36
nit - BytecodeOperandReadUnaligned(...)
oth
2016/03/21 14:21:49
Done.
| |
| 146 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | 152 int relative_offset, int count, MachineType msb_type) { |
|
rmcilroy
2016/03/21 12:41:36
Could we just pass the MachineType of the end resu
oth
2016/03/21 14:21:49
Done.
| |
| 147 DCHECK_EQ(OperandSize::kShort, | 153 static const int kMaxCount = 4; |
|
rmcilroy
2016/03/21 12:41:36
DCHECK(!TargetSupportsUnalignedAccess())
oth
2016/03/21 14:21:49
Done.
| |
| 148 Bytecodes::GetOperandSize(bytecode_, operand_index)); | 154 DCHECK(msb_type == MachineType::Int8() || msb_type == MachineType::Uint8()); |
| 149 if (TargetSupportsUnalignedAccess()) { | 155 DCHECK(count <= kMaxCount); |
| 150 return Load( | 156 |
| 151 MachineType::Uint16(), BytecodeArrayTaggedPointer(), | |
| 152 IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset( | |
| 153 bytecode_, operand_index)))); | |
| 154 } else { | |
| 155 int offset = Bytecodes::GetOperandOffset(bytecode_, operand_index); | |
| 156 Node* first_byte = | |
| 157 Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | |
| 158 IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset))); | |
| 159 Node* second_byte = | |
| 160 Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | |
| 161 IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset + 1))); | |
| 162 #if V8_TARGET_LITTLE_ENDIAN | 157 #if V8_TARGET_LITTLE_ENDIAN |
| 163 return WordOr(WordShl(second_byte, kBitsPerByte), first_byte); | 158 const int kStep = -1; |
| 159 int msb_offset = count - 1; | |
| 164 #elif V8_TARGET_BIG_ENDIAN | 160 #elif V8_TARGET_BIG_ENDIAN |
| 165 return WordOr(WordShl(first_byte, kBitsPerByte), second_byte); | 161 const int kStep = 1; |
| 162 int msb_offset = 0; | |
| 166 #else | 163 #else |
| 167 #error "Unknown Architecture" | 164 #error "Unknown Architecture" |
| 168 #endif | 165 #endif |
| 166 | |
| 167 // Read MSB into bytes[0]...LSB into bytes[count - 1] | |
| 168 compiler::Node* bytes[kMaxCount]; | |
| 169 for (int i = 0; i < count; i++) { | |
| 170 MachineType machine_type = (i == 0) ? msb_type : MachineType::Uint8(); | |
| 171 Node* offset = IntPtrConstant(relative_offset + msb_offset + i * kStep); | |
| 172 Node* array_offset = IntPtrAdd(BytecodeOffset(), offset); | |
| 173 bytes[i] = Load(machine_type, BytecodeArrayTaggedPointer(), array_offset); | |
| 174 } | |
| 175 | |
| 176 // Pack LSB to MSB. | |
| 177 Node* result = bytes[--count]; | |
| 178 for (int i = 1; --count >= 0; i++) { | |
| 179 Node* shift = Int32Constant(i * kBitsPerByte); | |
| 180 Node* value = Word32Shl(bytes[count], shift); | |
| 181 result = Word32Or(value, result); | |
| 182 } | |
| 183 return result; | |
| 184 } | |
| 185 | |
| 186 Node* InterpreterAssembler::BytecodeOperandUnsignedShort(int operand_index) { | |
| 187 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | |
| 188 DCHECK_EQ( | |
| 189 OperandSize::kShort, | |
| 190 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale())); | |
| 191 int operand_offset = | |
| 192 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); | |
| 193 if (TargetSupportsUnalignedAccess()) { | |
| 194 return Load(MachineType::Uint16(), BytecodeArrayTaggedPointer(), | |
| 195 IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); | |
| 196 } else { | |
| 197 return BytecodeReadUnalignedBytes(operand_offset, 2, MachineType::Uint8()); | |
| 169 } | 198 } |
| 170 } | 199 } |
| 171 | 200 |
| 172 Node* InterpreterAssembler::BytecodeOperandShortSignExtended( | 201 Node* InterpreterAssembler::BytecodeOperandSignedShort(int operand_index) { |
| 173 int operand_index) { | |
| 174 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | 202 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); |
| 175 DCHECK_EQ(OperandSize::kShort, | 203 DCHECK_EQ( |
| 176 Bytecodes::GetOperandSize(bytecode_, operand_index)); | 204 OperandSize::kShort, |
| 177 int operand_offset = Bytecodes::GetOperandOffset(bytecode_, operand_index); | 205 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale())); |
| 206 int operand_offset = | |
| 207 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); | |
| 178 Node* load; | 208 Node* load; |
| 179 if (TargetSupportsUnalignedAccess()) { | 209 if (TargetSupportsUnalignedAccess()) { |
| 180 load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(), | 210 load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(), |
| 181 IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); | 211 IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); |
| 182 } else { | 212 } else { |
| 183 #if V8_TARGET_LITTLE_ENDIAN | 213 load = BytecodeReadUnalignedBytes(operand_offset, 2, MachineType::Int8()); |
| 184 Node* hi_byte_offset = IntPtrConstant(operand_offset + 1); | |
| 185 Node* lo_byte_offset = IntPtrConstant(operand_offset); | |
| 186 #elif V8_TARGET_BIG_ENDIAN | |
| 187 Node* hi_byte_offset = IntPtrConstant(operand_offset); | |
| 188 Node* lo_byte_offset = IntPtrConstant(operand_offset + 1); | |
| 189 #else | |
| 190 #error "Unknown Architecture" | |
| 191 #endif | |
| 192 Node* hi_byte = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(), | |
| 193 IntPtrAdd(BytecodeOffset(), hi_byte_offset)); | |
| 194 Node* lo_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | |
| 195 IntPtrAdd(BytecodeOffset(), lo_byte_offset)); | |
| 196 hi_byte = Word32Shl(hi_byte, Int32Constant(kBitsPerByte)); | |
| 197 load = Word32Or(hi_byte, lo_byte); | |
| 198 } | 214 } |
| 199 | 215 |
| 200 // Ensure that we sign extend to full pointer size | 216 // Ensure that we sign extend to full pointer size |
| 201 if (kPointerSize == 8) { | 217 if (kPointerSize == 8) { |
| 202 load = ChangeInt32ToInt64(load); | 218 load = ChangeInt32ToInt64(load); |
| 203 } | 219 } |
| 204 return load; | 220 return load; |
| 205 } | 221 } |
| 206 | 222 |
| 207 Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) { | 223 Node* InterpreterAssembler::BytecodeOperandUnsignedQuad(int operand_index) { |
| 208 switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) { | 224 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); |
| 225 DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize( | |
| 226 bytecode_, operand_index, operand_scale())); | |
| 227 int operand_offset = | |
| 228 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); | |
| 229 if (TargetSupportsUnalignedAccess()) { | |
| 230 return Load(MachineType::Uint32(), BytecodeArrayTaggedPointer(), | |
| 231 IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); | |
| 232 } else { | |
| 233 return BytecodeReadUnalignedBytes(operand_offset, 4, MachineType::Uint8()); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 Node* InterpreterAssembler::BytecodeOperandSignedQuad(int operand_index) { | |
| 238 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); | |
| 239 DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize( | |
| 240 bytecode_, operand_index, operand_scale())); | |
| 241 int operand_offset = | |
| 242 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); | |
| 243 Node* load; | |
| 244 if (TargetSupportsUnalignedAccess()) { | |
| 245 load = Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), | |
| 246 IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); | |
| 247 } else { | |
| 248 load = BytecodeReadUnalignedBytes(operand_offset, 4, MachineType::Int8()); | |
| 249 } | |
| 250 | |
| 251 // Ensure that we sign extend to full pointer size | |
| 252 if (kPointerSize == 8) { | |
| 253 load = ChangeInt32ToInt64(load); | |
| 254 } | |
| 255 return load; | |
| 256 } | |
| 257 | |
| 258 Node* InterpreterAssembler::BytecodeSignedOperand(int operand_index, | |
| 259 OperandSize operand_size) { | |
| 260 DCHECK(!Bytecodes::IsUnsignedOperandType( | |
| 261 Bytecodes::GetOperandType(bytecode_, operand_index))); | |
| 262 switch (operand_size) { | |
| 209 case OperandSize::kByte: | 263 case OperandSize::kByte: |
| 210 DCHECK_EQ(OperandType::kRegCount8, | 264 return BytecodeOperandSignedByte(operand_index); |
| 211 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 212 return BytecodeOperand(operand_index); | |
| 213 case OperandSize::kShort: | 265 case OperandSize::kShort: |
| 214 DCHECK_EQ(OperandType::kRegCount16, | 266 return BytecodeOperandSignedShort(operand_index); |
| 215 Bytecodes::GetOperandType(bytecode_, operand_index)); | 267 case OperandSize::kQuad: |
| 216 return BytecodeOperandShort(operand_index); | 268 return BytecodeOperandSignedQuad(operand_index); |
| 217 case OperandSize::kNone: | 269 case OperandSize::kNone: |
| 218 UNREACHABLE(); | 270 UNREACHABLE(); |
| 219 } | 271 } |
| 220 return nullptr; | 272 return nullptr; |
| 221 } | 273 } |
| 222 | 274 |
| 223 Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { | 275 Node* InterpreterAssembler::BytecodeUnsignedOperand(int operand_index, |
| 224 DCHECK_EQ(OperandType::kImm8, | 276 OperandSize operand_size) { |
| 225 Bytecodes::GetOperandType(bytecode_, operand_index)); | 277 DCHECK(Bytecodes::IsUnsignedOperandType( |
| 226 return BytecodeOperandSignExtended(operand_index); | 278 Bytecodes::GetOperandType(bytecode_, operand_index))); |
| 227 } | 279 switch (operand_size) { |
| 228 | |
| 229 Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { | |
| 230 switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) { | |
| 231 case OperandSize::kByte: | 280 case OperandSize::kByte: |
| 232 DCHECK_EQ(OperandType::kIdx8, | 281 return BytecodeOperandUnsignedByte(operand_index); |
| 233 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 234 return BytecodeOperand(operand_index); | |
| 235 case OperandSize::kShort: | 282 case OperandSize::kShort: |
| 236 DCHECK_EQ(OperandType::kIdx16, | 283 return BytecodeOperandUnsignedShort(operand_index); |
| 237 Bytecodes::GetOperandType(bytecode_, operand_index)); | 284 case OperandSize::kQuad: |
| 238 return BytecodeOperandShort(operand_index); | 285 return BytecodeOperandUnsignedQuad(operand_index); |
| 239 case OperandSize::kNone: | 286 case OperandSize::kNone: |
| 240 UNREACHABLE(); | 287 UNREACHABLE(); |
| 241 } | 288 } |
| 242 return nullptr; | 289 return nullptr; |
| 243 } | 290 } |
| 244 | 291 |
| 292 Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) { | |
| 293 DCHECK_EQ(OperandType::kRegCount, | |
| 294 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 295 OperandSize operand_size = | |
| 296 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | |
| 297 return BytecodeUnsignedOperand(operand_index, operand_size); | |
| 298 } | |
| 299 | |
| 300 Node* InterpreterAssembler::BytecodeOperandFlag(int operand_index) { | |
| 301 DCHECK_EQ(OperandType::kFlag8, | |
| 302 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 303 OperandSize operand_size = | |
| 304 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | |
| 305 DCHECK_EQ(operand_size, OperandSize::kByte); | |
| 306 return BytecodeUnsignedOperand(operand_index, operand_size); | |
| 307 } | |
| 308 | |
| 309 Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { | |
| 310 DCHECK_EQ(OperandType::kImm, | |
| 311 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 312 OperandSize operand_size = | |
| 313 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | |
| 314 return BytecodeSignedOperand(operand_index, operand_size); | |
| 315 } | |
| 316 | |
| 317 Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { | |
| 318 DCHECK(OperandType::kIdx == | |
| 319 Bytecodes::GetOperandType(bytecode_, operand_index)); | |
| 320 OperandSize operand_size = | |
| 321 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); | |
| 322 return BytecodeUnsignedOperand(operand_index, operand_size); | |
| 323 } | |
| 324 | |
| 245 Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) { | 325 Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) { |
| 246 OperandType operand_type = | 326 DCHECK(Bytecodes::IsRegisterOperandType( |
| 247 Bytecodes::GetOperandType(bytecode_, operand_index); | 327 Bytecodes::GetOperandType(bytecode_, operand_index))); |
| 248 if (Bytecodes::IsRegisterOperandType(operand_type)) { | 328 OperandSize operand_size = |
| 249 OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type); | 329 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); |
| 250 if (operand_size == OperandSize::kByte) { | 330 return BytecodeSignedOperand(operand_index, operand_size); |
| 251 return BytecodeOperandSignExtended(operand_index); | 331 } |
| 252 } else if (operand_size == OperandSize::kShort) { | 332 |
| 253 return BytecodeOperandShortSignExtended(operand_index); | 333 Node* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) { |
| 254 } | 334 DCHECK(OperandType::kRuntimeId == |
| 255 } | 335 Bytecodes::GetOperandType(bytecode_, operand_index)); |
| 256 UNREACHABLE(); | 336 OperandSize operand_size = |
| 257 return nullptr; | 337 Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); |
| 338 DCHECK_EQ(operand_size, OperandSize::kShort); | |
| 339 return BytecodeUnsignedOperand(operand_index, operand_size); | |
| 258 } | 340 } |
| 259 | 341 |
| 260 Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { | 342 Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { |
| 261 Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), | 343 Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), |
| 262 BytecodeArray::kConstantPoolOffset); | 344 BytecodeArray::kConstantPoolOffset); |
| 263 Node* entry_offset = | 345 Node* entry_offset = |
| 264 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 346 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
| 265 WordShl(index, kPointerSizeLog2)); | 347 WordShl(index, kPointerSizeLog2)); |
| 266 return Load(MachineType::AnyTagged(), constant_pool, entry_offset); | 348 return Load(MachineType::AnyTagged(), constant_pool, entry_offset); |
| 267 } | 349 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 507 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
| 426 JumpConditional(WordEqual(lhs, rhs), delta); | 508 JumpConditional(WordEqual(lhs, rhs), delta); |
| 427 } | 509 } |
| 428 | 510 |
| 429 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, | 511 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, |
| 430 Node* delta) { | 512 Node* delta) { |
| 431 JumpConditional(WordNotEqual(lhs, rhs), delta); | 513 JumpConditional(WordNotEqual(lhs, rhs), delta); |
| 432 } | 514 } |
| 433 | 515 |
| 434 void InterpreterAssembler::Dispatch() { | 516 void InterpreterAssembler::Dispatch() { |
| 435 DispatchTo(Advance(Bytecodes::Size(bytecode_))); | 517 DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_))); |
| 436 } | 518 } |
| 437 | 519 |
| 438 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { | 520 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { |
| 439 Node* target_bytecode = Load( | 521 Node* target_bytecode = Load( |
| 440 MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); | 522 MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); |
| 441 if (kPointerSize == 8) { | 523 if (kPointerSize == 8) { |
| 442 target_bytecode = ChangeUint32ToUint64(target_bytecode); | 524 target_bytecode = ChangeUint32ToUint64(target_bytecode); |
| 443 } | 525 } |
| 444 | 526 |
| 445 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion | 527 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 457 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 539 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
| 458 } | 540 } |
| 459 | 541 |
| 460 InterpreterDispatchDescriptor descriptor(isolate()); | 542 InterpreterDispatchDescriptor descriptor(isolate()); |
| 461 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), | 543 Node* args[] = {GetAccumulator(), RegisterFileRawPointer(), |
| 462 bytecode_offset, BytecodeArrayTaggedPointer(), | 544 bytecode_offset, BytecodeArrayTaggedPointer(), |
| 463 DispatchTableRawPointer(), GetContext()}; | 545 DispatchTableRawPointer(), GetContext()}; |
| 464 TailCall(descriptor, handler, args, 0); | 546 TailCall(descriptor, handler, args, 0); |
| 465 } | 547 } |
| 466 | 548 |
| 549 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { | |
| 550 // Dispatching a wide bytecode - there are two bytes the prefix byte and | |
| 551 // the widended bytecode. The dispatch table is organized such that: | |
| 552 // Indices 0-255 correspond to bytecodes with operand_scale == 0 | |
| 553 // Indices 256-511 correspond to bytecodes with operand_scale == 1 | |
| 554 // Indices 512-7671 correspond to bytecodes with operand_scale == 2 | |
| 555 Node* next_bytecode_offset = Advance(1); | |
| 556 Node* next_bytecode = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | |
| 557 next_bytecode_offset); | |
| 558 if (kPointerSize == 8) { | |
| 559 next_bytecode = ChangeUint32ToUint64(next_bytecode); | |
| 560 } | |
| 561 Node* base_index; | |
| 562 switch (operand_scale) { | |
| 563 case OperandScale::kDouble: | |
| 564 base_index = IntPtrConstant(1 << kBitsPerByte); | |
| 565 break; | |
| 566 case OperandScale::kQuadruple: | |
| 567 base_index = IntPtrConstant(2 << kBitsPerByte); | |
| 568 break; | |
| 569 default: | |
| 570 UNREACHABLE(); | |
| 571 base_index = nullptr; | |
| 572 } | |
| 573 Node* target_index = IntPtrAdd(base_index, next_bytecode); | |
| 574 Node* target_code_object = | |
| 575 Load(MachineType::Pointer(), DispatchTableRawPointer(), | |
| 576 WordShl(target_index, kPointerSizeLog2)); | |
| 577 | |
| 578 DispatchToBytecodeHandler(target_code_object, next_bytecode_offset); | |
| 579 } | |
| 580 | |
| 467 void InterpreterAssembler::InterpreterReturn() { | 581 void InterpreterAssembler::InterpreterReturn() { |
| 468 // TODO(rmcilroy): Investigate whether it is worth supporting self | 582 // TODO(rmcilroy): Investigate whether it is worth supporting self |
| 469 // optimization of primitive functions like FullCodegen. | 583 // optimization of primitive functions like FullCodegen. |
| 470 | 584 |
| 471 // Update profiling count by -BytecodeOffset to simulate backedge to start of | 585 // Update profiling count by -BytecodeOffset to simulate backedge to start of |
| 472 // function. | 586 // function. |
| 473 Node* profiling_weight = | 587 Node* profiling_weight = |
| 474 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), | 588 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), |
| 475 BytecodeOffset()); | 589 BytecodeOffset()); |
| 476 UpdateInterruptBudget(profiling_weight); | 590 UpdateInterruptBudget(profiling_weight); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 V8_TARGET_ARCH_S390 | 649 V8_TARGET_ARCH_S390 |
| 536 return true; | 650 return true; |
| 537 #else | 651 #else |
| 538 #error "Unknown Architecture" | 652 #error "Unknown Architecture" |
| 539 #endif | 653 #endif |
| 540 } | 654 } |
| 541 | 655 |
| 542 } // namespace interpreter | 656 } // namespace interpreter |
| 543 } // namespace internal | 657 } // namespace internal |
| 544 } // namespace v8 | 658 } // namespace v8 |
| OLD | NEW |