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/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
6 #include "src/compiler.h" | 6 #include "src/compiler.h" |
7 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 namespace interpreter { | 10 namespace interpreter { |
11 | 11 |
12 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED { | 12 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED { |
13 public: | 13 public: |
14 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) | 14 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) |
15 : array_builder_(array_builder), | 15 : array_builder_(array_builder), |
16 previous_bytecode_start_(array_builder_.last_bytecode_start_) { | 16 previous_bytecode_start_(array_builder_.last_bytecode_start_) { |
17 // This helper is expected to be instantiated only when the last bytecode is | 17 // This helper is expected to be instantiated only when the last bytecode is |
18 // in the same basic block. | 18 // in the same basic block. |
19 DCHECK(array_builder_.LastBytecodeInSameBlock()); | 19 DCHECK(array_builder_.LastBytecodeInSameBlock()); |
20 bytecode_ = Bytecodes::FromByte( | |
21 array_builder_.bytecodes()->at(previous_bytecode_start_)); | |
22 operand_scale_ = OperandScale::k1X; | |
23 if (Bytecodes::IsPrefixScalingBytecode(bytecode_)) { | |
24 operand_scale_ = Bytecodes::PrefixBytecodeToOperandScale(bytecode_); | |
25 bytecode_ = Bytecodes::FromByte( | |
26 array_builder_.bytecodes()->at(previous_bytecode_start_ + 1)); | |
27 } | |
20 } | 28 } |
21 | 29 |
22 // Returns the previous bytecode in the same basic block. | 30 // Returns the previous bytecode in the same basic block. |
23 MUST_USE_RESULT Bytecode GetBytecode() const { | 31 MUST_USE_RESULT Bytecode GetBytecode() const { |
24 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | 32 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); |
25 return Bytecodes::FromByte( | 33 return bytecode_; |
26 array_builder_.bytecodes()->at(previous_bytecode_start_)); | |
27 } | 34 } |
28 | 35 |
29 // Returns the operand at operand_index for the previous bytecode in the | 36 MUST_USE_RESULT Register GetRegisterOperand(int operand_index) const { |
30 // same basic block. | 37 return Register::FromOperand(GetSignedOperand(operand_index)); |
31 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const { | 38 } |
39 | |
40 MUST_USE_RESULT uint32_t GetIndexOperand(int operand_index) const { | |
41 return GetUnsignedOperand(operand_index); | |
42 } | |
43 | |
44 Handle<Object> GetConstantForIndexOperand(int operand_index) const { | |
45 return array_builder_.constant_array_builder()->At( | |
46 GetIndexOperand(operand_index)); | |
47 } | |
48 | |
49 private: | |
50 // Returns the signed operand at operand_index for the previous | |
51 // bytecode in the same basic block. | |
52 MUST_USE_RESULT int32_t GetSignedOperand(int operand_index) const { | |
32 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | 53 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); |
33 Bytecode bytecode = GetBytecode(); | 54 OperandType operand_type = |
34 DCHECK_GE(operand_index, 0); | 55 Bytecodes::GetOperandType(bytecode_, operand_index); |
35 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); | 56 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); |
36 size_t operand_offset = | 57 size_t operand_offset = |
37 previous_bytecode_start_ + | 58 previous_bytecode_start_ + prefix_offset() + |
38 Bytecodes::GetOperandOffset(bytecode, operand_index); | 59 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale_); |
39 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); | 60 OperandSize operand_size = |
40 switch (size) { | 61 Bytecodes::SizeOfOperand(operand_type, operand_scale_); |
62 switch (operand_size) { | |
rmcilroy
2016/03/17 17:30:49
I think you could use DecodeSignedOperand here to
oth
2016/03/21 09:16:53
Done.
| |
63 case OperandSize::kByte: | |
64 return static_cast<int8_t>(GetOperand(operand_offset, operand_size)); | |
65 case OperandSize::kShort: | |
66 return static_cast<int16_t>(GetOperand(operand_offset, operand_size)); | |
67 case OperandSize::kQuad: | |
68 return static_cast<int32_t>(GetOperand(operand_offset, operand_size)); | |
41 case OperandSize::kNone: | 69 case OperandSize::kNone: |
42 UNREACHABLE(); | 70 UNREACHABLE(); |
43 break; | 71 break; |
44 case OperandSize::kByte: | |
45 return static_cast<uint32_t>( | |
46 array_builder_.bytecodes()->at(operand_offset)); | |
47 case OperandSize::kShort: | |
48 uint16_t operand = | |
49 (array_builder_.bytecodes()->at(operand_offset) << 8) + | |
50 array_builder_.bytecodes()->at(operand_offset + 1); | |
51 return static_cast<uint32_t>(operand); | |
52 } | 72 } |
53 return 0; | 73 return 0; |
54 } | 74 } |
55 | 75 |
56 Handle<Object> GetConstantForIndexOperand(int operand_index) const { | 76 // Returns the unsigned operand at operand_index for the previous |
57 return array_builder_.constant_array_builder()->At( | 77 // bytecode in the same basic block. |
58 GetOperand(operand_index)); | 78 MUST_USE_RESULT int32_t GetUnsignedOperand(int operand_index) const { |
rmcilroy
2016/03/17 17:30:49
should this return uint32_t instead?
oth
2016/03/21 09:16:53
Done.
| |
79 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
80 OperandType operand_type = | |
81 Bytecodes::GetOperandType(bytecode_, operand_index); | |
82 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type)); | |
83 size_t operand_offset = | |
84 previous_bytecode_start_ + prefix_offset() + | |
85 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale_); | |
86 return GetOperand(operand_offset, | |
87 Bytecodes::SizeOfOperand(operand_type, operand_scale_)); | |
59 } | 88 } |
60 | 89 |
61 private: | 90 MUST_USE_RESULT uint32_t GetOperand(size_t operand_offset, |
91 OperandSize operand_size) const { | |
92 DCHECK(operand_size >= OperandSize::kByte && | |
rmcilroy
2016/03/17 17:30:49
Just DCHECK_NE(operand_size, OperandSize::kNone) s
oth
2016/03/21 09:16:53
Function removed as part of common factoring of De
| |
93 operand_size <= OperandSize::kQuad); | |
94 uint32_t result = array_builder_.bytecodes()->at(operand_offset); | |
95 for (size_t i = 1; i < static_cast<size_t>(operand_size); ++i) { | |
96 result <<= 8; | |
97 result |= array_builder_.bytecodes()->at(operand_offset + 1); | |
98 } | |
99 return result; | |
100 } | |
101 | |
102 int prefix_offset() const { | |
103 return Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_) ? 1 | |
104 : 0; | |
105 } | |
106 | |
62 const BytecodeArrayBuilder& array_builder_; | 107 const BytecodeArrayBuilder& array_builder_; |
108 OperandScale operand_scale_; | |
109 Bytecode bytecode_; | |
63 size_t previous_bytecode_start_; | 110 size_t previous_bytecode_start_; |
64 | 111 |
65 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); | 112 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); |
66 }; | 113 }; |
67 | 114 |
68 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, | 115 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, |
69 int parameter_count, | 116 int parameter_count, |
70 int context_count, int locals_count, | 117 int context_count, int locals_count, |
71 FunctionLiteral* literal) | 118 FunctionLiteral* literal) |
72 : isolate_(isolate), | 119 : isolate_(isolate), |
73 zone_(zone), | 120 zone_(zone), |
74 bytecodes_(zone), | 121 bytecodes_(zone), |
75 bytecode_generated_(false), | 122 bytecode_generated_(false), |
76 constant_array_builder_(isolate, zone), | 123 constant_array_builder_(isolate, zone), |
77 handler_table_builder_(isolate, zone), | 124 handler_table_builder_(isolate, zone), |
78 source_position_table_builder_(isolate, zone), | 125 source_position_table_builder_(isolate, zone), |
79 last_block_end_(0), | 126 last_block_end_(0), |
80 last_bytecode_start_(~0), | 127 last_bytecode_start_(~0), |
81 exit_seen_in_block_(false), | 128 exit_seen_in_block_(false), |
82 unbound_jumps_(0), | 129 unbound_jumps_(0), |
83 parameter_count_(parameter_count), | 130 parameter_count_(parameter_count), |
84 local_register_count_(locals_count), | 131 local_register_count_(locals_count), |
85 context_register_count_(context_count), | 132 context_register_count_(context_count), |
86 temporary_allocator_(zone, fixed_register_count()), | 133 temporary_allocator_(zone, fixed_register_count()) { |
87 register_translator_(this) { | |
88 DCHECK_GE(parameter_count_, 0); | 134 DCHECK_GE(parameter_count_, 0); |
89 DCHECK_GE(context_register_count_, 0); | 135 DCHECK_GE(context_register_count_, 0); |
90 DCHECK_GE(local_register_count_, 0); | 136 DCHECK_GE(local_register_count_, 0); |
91 return_position_ = | 137 return_position_ = |
92 literal ? std::max(literal->start_position(), literal->end_position() - 1) | 138 literal ? std::max(literal->start_position(), literal->end_position() - 1) |
93 : RelocInfo::kNoPosition; | 139 : RelocInfo::kNoPosition; |
94 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 140 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( |
95 source_position_table_builder())); | 141 source_position_table_builder())); |
96 } | 142 } |
97 | 143 |
(...skipping 20 matching lines...) Expand all Loading... | |
118 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { | 164 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { |
119 return reg.is_parameter() || reg.index() < locals_count(); | 165 return reg.is_parameter() || reg.index() < locals_count(); |
120 } | 166 } |
121 | 167 |
122 | 168 |
123 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 169 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
124 DCHECK_EQ(bytecode_generated_, false); | 170 DCHECK_EQ(bytecode_generated_, false); |
125 DCHECK(exit_seen_in_block_); | 171 DCHECK(exit_seen_in_block_); |
126 | 172 |
127 int bytecode_size = static_cast<int>(bytecodes_.size()); | 173 int bytecode_size = static_cast<int>(bytecodes_.size()); |
128 int register_count = | 174 int register_count = fixed_and_temporary_register_count(); |
129 fixed_and_temporary_register_count() + translation_register_count(); | |
130 int frame_size = register_count * kPointerSize; | 175 int frame_size = register_count * kPointerSize; |
131 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); | 176 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); |
132 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 177 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
133 Handle<ByteArray> source_position_table = | 178 Handle<ByteArray> source_position_table = |
134 source_position_table_builder()->ToSourcePositionTable(); | 179 source_position_table_builder()->ToSourcePositionTable(); |
135 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( | 180 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( |
136 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), | 181 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), |
137 constant_pool); | 182 constant_pool); |
138 bytecode_array->set_handler_table(*handler_table); | 183 bytecode_array->set_handler_table(*handler_table); |
139 bytecode_array->set_source_position_table(*source_position_table); | 184 bytecode_array->set_source_position_table(*source_position_table); |
140 | 185 |
141 void* line_info = source_position_table_builder()->DetachJITHandlerData(); | 186 void* line_info = source_position_table_builder()->DetachJITHandlerData(); |
142 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( | 187 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( |
143 AbstractCode::cast(*bytecode_array), line_info)); | 188 AbstractCode::cast(*bytecode_array), line_info)); |
144 | 189 |
145 bytecode_generated_ = true; | 190 bytecode_generated_ = true; |
146 return bytecode_array; | 191 return bytecode_array; |
147 } | 192 } |
148 | 193 |
149 | |
150 template <size_t N> | 194 template <size_t N> |
151 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { | 195 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t (&operands)[N], |
196 OperandScale operand_scale) { | |
152 // Don't output dead code. | 197 // Don't output dead code. |
153 if (exit_seen_in_block_) return; | 198 if (exit_seen_in_block_) return; |
154 | 199 |
155 int operand_count = static_cast<int>(N); | 200 int operand_count = static_cast<int>(N); |
156 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); | 201 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); |
157 | 202 |
158 int register_operand_count = Bytecodes::NumberOfRegisterOperands(bytecode); | 203 last_bytecode_start_ = bytecodes()->size(); |
159 if (register_operand_count > 0) { | 204 // Emit prefix bytecode for scale if required. |
160 register_translator()->TranslateInputRegisters(bytecode, operands, | 205 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { |
161 operand_count); | 206 bytecodes()->push_back(Bytecodes::ToByte( |
207 Bytecodes::OperandScaleToPrefixBytecode(operand_scale))); | |
162 } | 208 } |
163 | 209 |
164 last_bytecode_start_ = bytecodes()->size(); | 210 // Emit bytecode. |
165 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 211 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
212 | |
213 // Emit operands. | |
166 for (int i = 0; i < operand_count; i++) { | 214 for (int i = 0; i < operand_count; i++) { |
167 DCHECK(OperandIsValid(bytecode, i, operands[i])); | 215 DCHECK(OperandIsValid(bytecode, operand_scale, i, operands[i])); |
168 switch (Bytecodes::GetOperandSize(bytecode, i)) { | 216 switch (Bytecodes::GetOperandSize(bytecode, i, operand_scale)) { |
169 case OperandSize::kNone: | 217 case OperandSize::kNone: |
170 UNREACHABLE(); | 218 UNREACHABLE(); |
171 break; | 219 break; |
172 case OperandSize::kByte: | 220 case OperandSize::kByte: |
173 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 221 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); |
174 break; | 222 break; |
175 case OperandSize::kShort: { | 223 case OperandSize::kShort: { |
176 uint8_t operand_bytes[2]; | 224 uint8_t operand_bytes[2]; |
177 WriteUnalignedUInt16(operand_bytes, operands[i]); | 225 WriteUnalignedUInt16(operand_bytes, operands[i]); |
178 bytecodes()->insert(bytecodes()->end(), operand_bytes, | 226 bytecodes()->insert(bytecodes()->end(), operand_bytes, |
179 operand_bytes + 2); | 227 operand_bytes + 2); |
180 break; | 228 break; |
181 } | 229 } |
230 case OperandSize::kQuad: { | |
231 uint8_t operand_bytes[4]; | |
232 WriteUnalignedUInt32(operand_bytes, operands[i]); | |
233 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
234 operand_bytes + 4); | |
235 break; | |
236 } | |
182 } | 237 } |
183 } | 238 } |
184 | |
185 if (register_operand_count > 0) { | |
186 register_translator()->TranslateOutputRegisters(); | |
187 } | |
188 } | 239 } |
189 | 240 |
190 | |
191 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | |
192 uint32_t operand1, uint32_t operand2, | |
193 uint32_t operand3) { | |
194 uint32_t operands[] = {operand0, operand1, operand2, operand3}; | |
195 Output(bytecode, operands); | |
196 } | |
197 | |
198 | |
199 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | |
200 uint32_t operand1, uint32_t operand2) { | |
201 uint32_t operands[] = {operand0, operand1, operand2}; | |
202 Output(bytecode, operands); | |
203 } | |
204 | |
205 | |
206 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | |
207 uint32_t operand1) { | |
208 uint32_t operands[] = {operand0, operand1}; | |
209 Output(bytecode, operands); | |
210 } | |
211 | |
212 | |
213 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | |
214 uint32_t operands[] = {operand0}; | |
215 Output(bytecode, operands); | |
216 } | |
217 | |
218 | |
219 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 241 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
220 // Don't output dead code. | 242 // Don't output dead code. |
221 if (exit_seen_in_block_) return; | 243 if (exit_seen_in_block_) return; |
222 | 244 |
223 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 245 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
224 last_bytecode_start_ = bytecodes()->size(); | 246 last_bytecode_start_ = bytecodes()->size(); |
225 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 247 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
226 } | 248 } |
227 | 249 |
250 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | |
251 OperandScale operand_scale, | |
252 uint32_t operand0, uint32_t operand1, | |
253 uint32_t operand2, uint32_t operand3) { | |
254 uint32_t operands[] = {operand0, operand1, operand2, operand3}; | |
255 Output(bytecode, operands, operand_scale); | |
256 } | |
257 | |
258 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | |
259 OperandScale operand_scale, | |
260 uint32_t operand0, uint32_t operand1, | |
261 uint32_t operand2) { | |
262 uint32_t operands[] = {operand0, operand1, operand2}; | |
263 Output(bytecode, operands, operand_scale); | |
264 } | |
265 | |
266 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | |
267 OperandScale operand_scale, | |
268 uint32_t operand0, uint32_t operand1) { | |
269 uint32_t operands[] = {operand0, operand1}; | |
270 Output(bytecode, operands, operand_scale); | |
271 } | |
272 | |
273 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | |
274 OperandScale operand_scale, | |
275 uint32_t operand0) { | |
276 uint32_t operands[] = {operand0}; | |
277 Output(bytecode, operands, operand_scale); | |
278 } | |
279 | |
228 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 280 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
229 Register reg) { | 281 Register reg) { |
230 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand()); | 282 OperandScale operand_scale = OperandSizesToScale(SizeForRegisterOperand(reg)); |
283 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, | |
284 RegisterOperand(reg)); | |
231 return *this; | 285 return *this; |
232 } | 286 } |
233 | 287 |
234 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { | 288 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { |
235 Output(BytecodeForCountOperation(op)); | 289 Output(BytecodeForCountOperation(op)); |
236 return *this; | 290 return *this; |
237 } | 291 } |
238 | 292 |
239 | 293 |
240 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 294 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
241 Output(Bytecode::kLogicalNot); | 295 Output(Bytecode::kLogicalNot); |
242 return *this; | 296 return *this; |
243 } | 297 } |
244 | 298 |
245 | 299 |
246 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 300 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
247 Output(Bytecode::kTypeOf); | 301 Output(Bytecode::kTypeOf); |
248 return *this; | 302 return *this; |
249 } | 303 } |
250 | 304 |
251 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, | 305 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, |
252 Register reg) { | 306 Register reg) { |
253 Output(BytecodeForCompareOperation(op), reg.ToRawOperand()); | 307 OperandScale operand_scale = OperandSizesToScale(SizeForRegisterOperand(reg)); |
308 OutputScaled(BytecodeForCompareOperation(op), operand_scale, | |
309 RegisterOperand(reg)); | |
254 return *this; | 310 return *this; |
255 } | 311 } |
256 | 312 |
257 | 313 |
258 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 314 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
259 v8::internal::Smi* smi) { | 315 v8::internal::Smi* smi) { |
260 int32_t raw_smi = smi->value(); | 316 int32_t raw_smi = smi->value(); |
261 if (raw_smi == 0) { | 317 if (raw_smi == 0) { |
262 Output(Bytecode::kLdaZero); | 318 Output(Bytecode::kLdaZero); |
263 } else if (raw_smi >= -128 && raw_smi <= 127) { | |
264 Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); | |
265 } else { | 319 } else { |
266 LoadLiteral(Handle<Object>(smi, isolate_)); | 320 OperandSize operand_size = SizeForSignedOperand(raw_smi); |
321 OperandScale operand_scale = OperandSizesToScale(operand_size); | |
322 OutputScaled(Bytecode::kLdaSmi, operand_scale, | |
323 SignedOperand(raw_smi, operand_size)); | |
267 } | 324 } |
268 return *this; | 325 return *this; |
269 } | 326 } |
270 | 327 |
271 | 328 |
272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { | 329 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
273 size_t entry = GetConstantPoolEntry(object); | 330 size_t entry = GetConstantPoolEntry(object); |
274 if (FitsInIdx8Operand(entry)) { | 331 OperandScale operand_scale = |
275 Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry)); | 332 OperandSizesToScale(SizeForUnsignedOperand(entry)); |
276 } else if (FitsInIdx16Operand(entry)) { | 333 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); |
277 Output(Bytecode::kLdaConstantWide, static_cast<uint16_t>(entry)); | |
278 } else { | |
279 UNIMPLEMENTED(); | |
280 } | |
281 return *this; | 334 return *this; |
282 } | 335 } |
283 | 336 |
284 | 337 |
285 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | 338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
286 Output(Bytecode::kLdaUndefined); | 339 Output(Bytecode::kLdaUndefined); |
287 return *this; | 340 return *this; |
288 } | 341 } |
289 | 342 |
290 | 343 |
(...skipping 26 matching lines...) Expand all Loading... | |
317 LoadTrue(); | 370 LoadTrue(); |
318 } else { | 371 } else { |
319 LoadFalse(); | 372 LoadFalse(); |
320 } | 373 } |
321 return *this; | 374 return *this; |
322 } | 375 } |
323 | 376 |
324 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 377 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
325 Register reg) { | 378 Register reg) { |
326 if (!IsRegisterInAccumulator(reg)) { | 379 if (!IsRegisterInAccumulator(reg)) { |
327 Output(Bytecode::kLdar, reg.ToRawOperand()); | 380 OperandScale operand_scale = |
381 OperandSizesToScale(SizeForRegisterOperand(reg)); | |
382 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); | |
328 } | 383 } |
329 return *this; | 384 return *this; |
330 } | 385 } |
331 | 386 |
332 | 387 |
333 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 388 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
334 Register reg) { | 389 Register reg) { |
335 if (!IsRegisterInAccumulator(reg)) { | 390 if (!IsRegisterInAccumulator(reg)) { |
336 Output(Bytecode::kStar, reg.ToRawOperand()); | 391 OperandScale operand_scale = |
392 OperandSizesToScale(SizeForRegisterOperand(reg)); | |
393 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); | |
337 } | 394 } |
338 return *this; | 395 return *this; |
339 } | 396 } |
340 | 397 |
341 | 398 |
342 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 399 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
343 Register to) { | 400 Register to) { |
344 DCHECK(from != to); | 401 DCHECK(from != to); |
345 if (FitsInReg8Operand(from) && FitsInReg8Operand(to)) { | 402 OperandScale operand_scale = OperandSizesToScale(SizeForRegisterOperand(from), |
346 Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand()); | 403 SizeForRegisterOperand(to)); |
347 } else if (FitsInReg16Operand(from) && FitsInReg16Operand(to)) { | 404 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), |
348 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand()); | 405 RegisterOperand(to)); |
349 } else { | |
350 UNIMPLEMENTED(); | |
351 } | |
352 return *this; | 406 return *this; |
353 } | 407 } |
354 | 408 |
355 void BytecodeArrayBuilder::MoveRegisterUntranslated(Register from, | |
356 Register to) { | |
357 // Move bytecodes modify the stack. Checking validity is an | |
358 // essential mitigation against corrupting the stack. | |
359 if (FitsInReg8OperandUntranslated(from)) { | |
360 CHECK(RegisterIsValid(from, OperandType::kReg8) && | |
361 RegisterIsValid(to, OperandType::kReg16)); | |
362 } else if (FitsInReg8OperandUntranslated(to)) { | |
363 CHECK(RegisterIsValid(from, OperandType::kReg16) && | |
364 RegisterIsValid(to, OperandType::kReg8)); | |
365 } else { | |
366 UNIMPLEMENTED(); | |
367 } | |
368 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand()); | |
369 } | |
370 | |
371 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 409 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
372 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { | 410 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { |
373 // TODO(rmcilroy): Potentially store typeof information in an | 411 // TODO(rmcilroy): Potentially store typeof information in an |
374 // operand rather than having extra bytecodes. | 412 // operand rather than having extra bytecodes. |
375 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 413 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); |
376 size_t name_index = GetConstantPoolEntry(name); | 414 size_t name_index = GetConstantPoolEntry(name); |
377 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 415 OperandScale operand_scale = |
378 Output(bytecode, static_cast<uint8_t>(name_index), | 416 OperandSizesToScale(SizeForUnsignedOperand(name_index), |
379 static_cast<uint8_t>(feedback_slot)); | 417 SizeForUnsignedOperand(feedback_slot)); |
380 } else if (FitsInIdx16Operand(name_index) && | 418 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
381 FitsInIdx16Operand(feedback_slot)) { | 419 UnsignedOperand(feedback_slot)); |
382 Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index), | |
383 static_cast<uint16_t>(feedback_slot)); | |
384 } else { | |
385 UNIMPLEMENTED(); | |
386 } | |
387 return *this; | 420 return *this; |
388 } | 421 } |
389 | 422 |
390 | |
391 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 423 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
392 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 424 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
393 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | 425 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); |
394 size_t name_index = GetConstantPoolEntry(name); | 426 size_t name_index = GetConstantPoolEntry(name); |
395 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 427 OperandScale operand_scale = |
396 Output(bytecode, static_cast<uint8_t>(name_index), | 428 OperandSizesToScale(SizeForUnsignedOperand(name_index), |
397 static_cast<uint8_t>(feedback_slot)); | 429 SizeForUnsignedOperand(feedback_slot)); |
398 } else if (FitsInIdx16Operand(name_index) && | 430 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
399 FitsInIdx16Operand(feedback_slot)) { | 431 UnsignedOperand(feedback_slot)); |
400 Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index), | |
401 static_cast<uint16_t>(feedback_slot)); | |
402 } else { | |
403 UNIMPLEMENTED(); | |
404 } | |
405 return *this; | 432 return *this; |
406 } | 433 } |
407 | 434 |
408 | 435 |
409 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 436 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
410 int slot_index) { | 437 int slot_index) { |
411 DCHECK(slot_index >= 0); | 438 OperandScale operand_scale = OperandSizesToScale( |
412 if (FitsInIdx8Operand(slot_index)) { | 439 SizeForRegisterOperand(context), SizeForUnsignedOperand(slot_index)); |
413 Output(Bytecode::kLdaContextSlot, context.ToRawOperand(), | 440 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, |
414 static_cast<uint8_t>(slot_index)); | 441 RegisterOperand(context), UnsignedOperand(slot_index)); |
415 } else if (FitsInIdx16Operand(slot_index)) { | |
416 Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(), | |
417 static_cast<uint16_t>(slot_index)); | |
418 } else { | |
419 UNIMPLEMENTED(); | |
420 } | |
421 return *this; | 442 return *this; |
422 } | 443 } |
423 | 444 |
424 | 445 |
425 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 446 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
426 int slot_index) { | 447 int slot_index) { |
427 DCHECK(slot_index >= 0); | 448 OperandScale operand_scale = OperandSizesToScale( |
428 if (FitsInIdx8Operand(slot_index)) { | 449 SizeForRegisterOperand(context), SizeForUnsignedOperand(slot_index)); |
429 Output(Bytecode::kStaContextSlot, context.ToRawOperand(), | 450 OutputScaled(Bytecode::kStaContextSlot, operand_scale, |
430 static_cast<uint8_t>(slot_index)); | 451 RegisterOperand(context), UnsignedOperand(slot_index)); |
431 } else if (FitsInIdx16Operand(slot_index)) { | |
432 Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(), | |
433 static_cast<uint16_t>(slot_index)); | |
434 } else { | |
435 UNIMPLEMENTED(); | |
436 } | |
437 return *this; | 452 return *this; |
438 } | 453 } |
439 | 454 |
440 | |
441 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 455 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
442 const Handle<String> name, TypeofMode typeof_mode) { | 456 const Handle<String> name, TypeofMode typeof_mode) { |
443 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 457 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
444 ? Bytecode::kLdaLookupSlotInsideTypeof | 458 ? Bytecode::kLdaLookupSlotInsideTypeof |
445 : Bytecode::kLdaLookupSlot; | 459 : Bytecode::kLdaLookupSlot; |
446 size_t name_index = GetConstantPoolEntry(name); | 460 size_t name_index = GetConstantPoolEntry(name); |
447 if (FitsInIdx8Operand(name_index)) { | 461 OperandScale operand_scale = |
448 Output(bytecode, static_cast<uint8_t>(name_index)); | 462 OperandSizesToScale(SizeForUnsignedOperand(name_index)); |
449 } else if (FitsInIdx16Operand(name_index)) { | 463 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
450 Output(BytecodeForWideOperands(bytecode), | |
451 static_cast<uint16_t>(name_index)); | |
452 } else { | |
453 UNIMPLEMENTED(); | |
454 } | |
455 return *this; | 464 return *this; |
456 } | 465 } |
457 | 466 |
458 | |
459 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 467 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
460 const Handle<String> name, LanguageMode language_mode) { | 468 const Handle<String> name, LanguageMode language_mode) { |
461 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | 469 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); |
462 size_t name_index = GetConstantPoolEntry(name); | 470 size_t name_index = GetConstantPoolEntry(name); |
463 if (FitsInIdx8Operand(name_index)) { | 471 OperandScale operand_scale = |
464 Output(bytecode, static_cast<uint8_t>(name_index)); | 472 OperandSizesToScale(SizeForUnsignedOperand(name_index)); |
465 } else if (FitsInIdx16Operand(name_index)) { | 473 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
466 Output(BytecodeForWideOperands(bytecode), | |
467 static_cast<uint16_t>(name_index)); | |
468 } else { | |
469 UNIMPLEMENTED(); | |
470 } | |
471 return *this; | 474 return *this; |
472 } | 475 } |
473 | 476 |
474 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 477 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
475 Register object, const Handle<Name> name, int feedback_slot) { | 478 Register object, const Handle<Name> name, int feedback_slot) { |
476 size_t name_index = GetConstantPoolEntry(name); | 479 size_t name_index = GetConstantPoolEntry(name); |
477 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 480 OperandScale operand_scale = OperandSizesToScale( |
478 Output(Bytecode::kLoadIC, object.ToRawOperand(), | 481 SizeForRegisterOperand(object), SizeForUnsignedOperand(name_index), |
479 static_cast<uint8_t>(name_index), | 482 SizeForUnsignedOperand(feedback_slot)); |
480 static_cast<uint8_t>(feedback_slot)); | 483 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object), |
481 } else if (FitsInIdx16Operand(name_index) && | 484 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
482 FitsInIdx16Operand(feedback_slot)) { | |
483 Output(Bytecode::kLoadICWide, object.ToRawOperand(), | |
484 static_cast<uint16_t>(name_index), | |
485 static_cast<uint16_t>(feedback_slot)); | |
486 } else { | |
487 UNIMPLEMENTED(); | |
488 } | |
489 return *this; | 485 return *this; |
490 } | 486 } |
491 | 487 |
492 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 488 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
493 Register object, int feedback_slot) { | 489 Register object, int feedback_slot) { |
494 if (FitsInIdx8Operand(feedback_slot)) { | 490 OperandScale operand_scale = OperandSizesToScale( |
495 Output(Bytecode::kKeyedLoadIC, object.ToRawOperand(), | 491 SizeForRegisterOperand(object), SizeForUnsignedOperand(feedback_slot)); |
496 static_cast<uint8_t>(feedback_slot)); | 492 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object), |
497 } else if (FitsInIdx16Operand(feedback_slot)) { | 493 UnsignedOperand(feedback_slot)); |
498 Output(Bytecode::kKeyedLoadICWide, object.ToRawOperand(), | |
499 static_cast<uint16_t>(feedback_slot)); | |
500 } else { | |
501 UNIMPLEMENTED(); | |
502 } | |
503 return *this; | 494 return *this; |
504 } | 495 } |
505 | 496 |
506 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 497 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
507 Register object, const Handle<Name> name, int feedback_slot, | 498 Register object, const Handle<Name> name, int feedback_slot, |
508 LanguageMode language_mode) { | 499 LanguageMode language_mode) { |
509 Bytecode bytecode = BytecodeForStoreIC(language_mode); | 500 Bytecode bytecode = BytecodeForStoreIC(language_mode); |
510 size_t name_index = GetConstantPoolEntry(name); | 501 size_t name_index = GetConstantPoolEntry(name); |
511 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { | 502 OperandScale operand_scale = OperandSizesToScale( |
512 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index), | 503 SizeForRegisterOperand(object), SizeForUnsignedOperand(name_index), |
513 static_cast<uint8_t>(feedback_slot)); | 504 SizeForUnsignedOperand(feedback_slot)); |
514 } else if (FitsInIdx16Operand(name_index) && | 505 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
515 FitsInIdx16Operand(feedback_slot)) { | 506 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
516 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | |
517 static_cast<uint16_t>(name_index), | |
518 static_cast<uint16_t>(feedback_slot)); | |
519 } else { | |
520 UNIMPLEMENTED(); | |
521 } | |
522 return *this; | 507 return *this; |
523 } | 508 } |
524 | 509 |
525 | 510 |
526 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 511 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
527 Register object, Register key, int feedback_slot, | 512 Register object, Register key, int feedback_slot, |
528 LanguageMode language_mode) { | 513 LanguageMode language_mode) { |
529 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); | 514 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); |
530 if (FitsInIdx8Operand(feedback_slot)) { | 515 OperandScale operand_scale = OperandSizesToScale( |
531 Output(bytecode, object.ToRawOperand(), key.ToRawOperand(), | 516 SizeForRegisterOperand(object), SizeForRegisterOperand(key), |
532 static_cast<uint8_t>(feedback_slot)); | 517 SizeForUnsignedOperand(feedback_slot)); |
533 } else if (FitsInIdx16Operand(feedback_slot)) { | 518 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
534 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), | 519 RegisterOperand(key), UnsignedOperand(feedback_slot)); |
535 key.ToRawOperand(), static_cast<uint16_t>(feedback_slot)); | |
536 } else { | |
537 UNIMPLEMENTED(); | |
538 } | |
539 return *this; | 520 return *this; |
540 } | 521 } |
541 | 522 |
542 | 523 |
543 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( | 524 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( |
544 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { | 525 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { |
545 size_t entry = GetConstantPoolEntry(shared_info); | 526 size_t entry = GetConstantPoolEntry(shared_info); |
546 DCHECK(FitsInImm8Operand(tenured)); | 527 OperandScale operand_scale = |
547 if (FitsInIdx8Operand(entry)) { | 528 OperandSizesToScale(SizeForUnsignedOperand(entry)); |
548 Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry), | 529 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), |
549 static_cast<uint8_t>(tenured)); | 530 UnsignedOperand(static_cast<size_t>(tenured))); |
550 } else if (FitsInIdx16Operand(entry)) { | |
551 Output(Bytecode::kCreateClosureWide, static_cast<uint16_t>(entry), | |
552 static_cast<uint8_t>(tenured)); | |
553 } else { | |
554 UNIMPLEMENTED(); | |
555 } | |
556 return *this; | 531 return *this; |
557 } | 532 } |
558 | 533 |
559 | 534 |
560 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 535 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
561 CreateArgumentsType type) { | 536 CreateArgumentsType type) { |
562 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 537 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather |
563 // than having two different bytecodes once we have better support for | 538 // than having two different bytecodes once we have better support for |
564 // branches in the InterpreterAssembler. | 539 // branches in the InterpreterAssembler. |
565 Bytecode bytecode = BytecodeForCreateArguments(type); | 540 Bytecode bytecode = BytecodeForCreateArguments(type); |
566 Output(bytecode); | 541 Output(bytecode); |
567 return *this; | 542 return *this; |
568 } | 543 } |
569 | 544 |
570 | 545 |
571 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 546 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
572 Handle<String> pattern, int literal_index, int flags) { | 547 Handle<String> pattern, int literal_index, int flags) { |
573 DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. | |
574 size_t pattern_entry = GetConstantPoolEntry(pattern); | 548 size_t pattern_entry = GetConstantPoolEntry(pattern); |
575 if (FitsInIdx8Operand(literal_index) && FitsInIdx8Operand(pattern_entry)) { | 549 OperandScale operand_scale = OperandSizesToScale( |
576 Output(Bytecode::kCreateRegExpLiteral, static_cast<uint8_t>(pattern_entry), | 550 SizeForUnsignedOperand(pattern_entry), |
577 static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags)); | 551 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); |
578 } else if (FitsInIdx16Operand(literal_index) && | 552 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, |
579 FitsInIdx16Operand(pattern_entry)) { | 553 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), |
580 Output(Bytecode::kCreateRegExpLiteralWide, | 554 UnsignedOperand(flags)); |
581 static_cast<uint16_t>(pattern_entry), | |
582 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); | |
583 } else { | |
584 UNIMPLEMENTED(); | |
585 } | |
586 return *this; | 555 return *this; |
587 } | 556 } |
588 | 557 |
589 | 558 |
590 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( | 559 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( |
591 Handle<FixedArray> constant_elements, int literal_index, int flags) { | 560 Handle<FixedArray> constant_elements, int literal_index, int flags) { |
592 DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. | |
593 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); | 561 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); |
594 if (FitsInIdx8Operand(literal_index) && | 562 OperandScale operand_scale = OperandSizesToScale( |
595 FitsInIdx8Operand(constant_elements_entry)) { | 563 SizeForUnsignedOperand(constant_elements_entry), |
596 Output(Bytecode::kCreateArrayLiteral, | 564 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); |
597 static_cast<uint8_t>(constant_elements_entry), | 565 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, |
598 static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags)); | 566 UnsignedOperand(constant_elements_entry), |
599 } else if (FitsInIdx16Operand(literal_index) && | 567 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
600 FitsInIdx16Operand(constant_elements_entry)) { | |
601 Output(Bytecode::kCreateArrayLiteralWide, | |
602 static_cast<uint16_t>(constant_elements_entry), | |
603 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); | |
604 } else { | |
605 UNIMPLEMENTED(); | |
606 } | |
607 return *this; | 568 return *this; |
608 } | 569 } |
609 | 570 |
610 | 571 |
611 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( | 572 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( |
612 Handle<FixedArray> constant_properties, int literal_index, int flags) { | 573 Handle<FixedArray> constant_properties, int literal_index, int flags) { |
613 DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. | |
614 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); | 574 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); |
615 if (FitsInIdx8Operand(literal_index) && | 575 OperandScale operand_scale = OperandSizesToScale( |
616 FitsInIdx8Operand(constant_properties_entry)) { | 576 SizeForUnsignedOperand(constant_properties_entry), |
617 Output(Bytecode::kCreateObjectLiteral, | 577 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); |
618 static_cast<uint8_t>(constant_properties_entry), | 578 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, |
619 static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags)); | 579 UnsignedOperand(constant_properties_entry), |
620 } else if (FitsInIdx16Operand(literal_index) && | 580 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
621 FitsInIdx16Operand(constant_properties_entry)) { | |
622 Output(Bytecode::kCreateObjectLiteralWide, | |
623 static_cast<uint16_t>(constant_properties_entry), | |
624 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); | |
625 } else { | |
626 UNIMPLEMENTED(); | |
627 } | |
628 return *this; | 581 return *this; |
629 } | 582 } |
630 | 583 |
631 | 584 |
632 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { | 585 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { |
633 Output(Bytecode::kPushContext, context.ToRawOperand()); | 586 OperandScale operand_scale = |
587 OperandSizesToScale(SizeForRegisterOperand(context)); | |
588 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); | |
634 return *this; | 589 return *this; |
635 } | 590 } |
636 | 591 |
637 | 592 |
638 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 593 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
639 Output(Bytecode::kPopContext, context.ToRawOperand()); | 594 OperandScale operand_scale = |
595 OperandSizesToScale(SizeForRegisterOperand(context)); | |
596 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); | |
640 return *this; | 597 return *this; |
641 } | 598 } |
642 | 599 |
643 | 600 |
644 bool BytecodeArrayBuilder::NeedToBooleanCast() { | 601 bool BytecodeArrayBuilder::NeedToBooleanCast() { |
645 if (!LastBytecodeInSameBlock()) { | 602 if (!LastBytecodeInSameBlock()) { |
646 return true; | 603 return true; |
647 } | 604 } |
648 PreviousBytecodeHelper previous_bytecode(*this); | 605 PreviousBytecodeHelper previous_bytecode(*this); |
649 switch (previous_bytecode.GetBytecode()) { | 606 switch (previous_bytecode.GetBytecode()) { |
(...skipping 24 matching lines...) Expand all Loading... | |
674 } | 631 } |
675 | 632 |
676 | 633 |
677 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { | 634 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { |
678 if (LastBytecodeInSameBlock()) { | 635 if (LastBytecodeInSameBlock()) { |
679 PreviousBytecodeHelper previous_bytecode(*this); | 636 PreviousBytecodeHelper previous_bytecode(*this); |
680 switch (previous_bytecode.GetBytecode()) { | 637 switch (previous_bytecode.GetBytecode()) { |
681 case Bytecode::kToName: | 638 case Bytecode::kToName: |
682 case Bytecode::kTypeOf: | 639 case Bytecode::kTypeOf: |
683 return *this; | 640 return *this; |
684 case Bytecode::kLdaConstantWide: | |
685 case Bytecode::kLdaConstant: { | 641 case Bytecode::kLdaConstant: { |
686 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); | 642 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); |
687 if (object->IsName()) return *this; | 643 if (object->IsName()) return *this; |
688 break; | 644 break; |
689 } | 645 } |
690 default: | 646 default: |
691 break; | 647 break; |
692 } | 648 } |
693 } | 649 } |
694 Output(Bytecode::kToName); | 650 Output(Bytecode::kToName); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
747 case Bytecode::kJumpIfToBooleanFalse: | 703 case Bytecode::kJumpIfToBooleanFalse: |
748 return Bytecode::kJumpIfToBooleanFalseConstant; | 704 return Bytecode::kJumpIfToBooleanFalseConstant; |
749 case Bytecode::kJumpIfNotHole: | 705 case Bytecode::kJumpIfNotHole: |
750 return Bytecode::kJumpIfNotHoleConstant; | 706 return Bytecode::kJumpIfNotHoleConstant; |
751 case Bytecode::kJumpIfNull: | 707 case Bytecode::kJumpIfNull: |
752 return Bytecode::kJumpIfNullConstant; | 708 return Bytecode::kJumpIfNullConstant; |
753 case Bytecode::kJumpIfUndefined: | 709 case Bytecode::kJumpIfUndefined: |
754 return Bytecode::kJumpIfUndefinedConstant; | 710 return Bytecode::kJumpIfUndefinedConstant; |
755 default: | 711 default: |
756 UNREACHABLE(); | 712 UNREACHABLE(); |
757 return static_cast<Bytecode>(-1); | 713 return Bytecode::kIllegal; |
758 } | 714 } |
759 } | 715 } |
760 | 716 |
761 | |
762 // static | |
763 Bytecode BytecodeArrayBuilder::GetJumpWithConstantWideOperand( | |
764 Bytecode jump_bytecode) { | |
765 switch (jump_bytecode) { | |
766 case Bytecode::kJump: | |
767 return Bytecode::kJumpConstantWide; | |
768 case Bytecode::kJumpIfTrue: | |
769 return Bytecode::kJumpIfTrueConstantWide; | |
770 case Bytecode::kJumpIfFalse: | |
771 return Bytecode::kJumpIfFalseConstantWide; | |
772 case Bytecode::kJumpIfToBooleanTrue: | |
773 return Bytecode::kJumpIfToBooleanTrueConstantWide; | |
774 case Bytecode::kJumpIfToBooleanFalse: | |
775 return Bytecode::kJumpIfToBooleanFalseConstantWide; | |
776 case Bytecode::kJumpIfNotHole: | |
777 return Bytecode::kJumpIfNotHoleConstantWide; | |
778 case Bytecode::kJumpIfNull: | |
779 return Bytecode::kJumpIfNullConstantWide; | |
780 case Bytecode::kJumpIfUndefined: | |
781 return Bytecode::kJumpIfUndefinedConstantWide; | |
782 default: | |
783 UNREACHABLE(); | |
784 return static_cast<Bytecode>(-1); | |
785 } | |
786 } | |
787 | |
788 | |
789 // static | 717 // static |
790 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { | 718 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { |
791 switch (jump_bytecode) { | 719 switch (jump_bytecode) { |
792 case Bytecode::kJump: | 720 case Bytecode::kJump: |
793 case Bytecode::kJumpIfNull: | 721 case Bytecode::kJumpIfNull: |
794 case Bytecode::kJumpIfUndefined: | 722 case Bytecode::kJumpIfUndefined: |
795 case Bytecode::kJumpIfNotHole: | 723 case Bytecode::kJumpIfNotHole: |
796 return jump_bytecode; | 724 return jump_bytecode; |
797 case Bytecode::kJumpIfTrue: | 725 case Bytecode::kJumpIfTrue: |
798 return Bytecode::kJumpIfToBooleanTrue; | 726 return Bytecode::kJumpIfToBooleanTrue; |
799 case Bytecode::kJumpIfFalse: | 727 case Bytecode::kJumpIfFalse: |
800 return Bytecode::kJumpIfToBooleanFalse; | 728 return Bytecode::kJumpIfToBooleanFalse; |
801 default: | 729 default: |
802 UNREACHABLE(); | 730 UNREACHABLE(); |
803 } | 731 } |
804 return static_cast<Bytecode>(-1); | 732 return Bytecode::kIllegal; |
805 } | 733 } |
806 | 734 |
807 | 735 |
808 void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand( | 736 void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand( |
809 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 737 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { |
810 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | 738 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); |
811 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | 739 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
812 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 740 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; |
813 DCHECK_EQ(*operand_location, 0); | 741 DCHECK_EQ(*operand_location, 0); |
814 if (FitsInImm8Operand(delta)) { | 742 if (SizeForSignedOperand(delta) == OperandSize::kByte) { |
815 // The jump fits within the range of an Imm8 operand, so cancel | 743 // The jump fits within the range of an Imm operand, so cancel |
816 // the reservation and jump directly. | 744 // the reservation and jump directly. |
817 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); | 745 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); |
818 *operand_location = static_cast<uint8_t>(delta); | 746 *operand_location = static_cast<uint8_t>(delta); |
819 } else { | 747 } else { |
820 // The jump does not fit within the range of an Imm8 operand, so | 748 // The jump does not fit within the range of an Imm operand, so |
821 // commit reservation putting the offset into the constant pool, | 749 // commit reservation putting the offset into the constant pool, |
822 // and update the jump instruction and operand. | 750 // and update the jump instruction and operand. |
823 size_t entry = constant_array_builder()->CommitReservedEntry( | 751 size_t entry = constant_array_builder()->CommitReservedEntry( |
824 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); | 752 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); |
825 DCHECK(FitsInIdx8Operand(entry)); | 753 DCHECK(SizeForUnsignedOperand(entry) == OperandSize::kByte); |
826 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | 754 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
827 *jump_location = Bytecodes::ToByte(jump_bytecode); | 755 *jump_location = Bytecodes::ToByte(jump_bytecode); |
828 *operand_location = static_cast<uint8_t>(entry); | 756 *operand_location = static_cast<uint8_t>(entry); |
829 } | 757 } |
830 } | 758 } |
831 | 759 |
832 | |
833 void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand( | 760 void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand( |
834 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 761 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { |
835 DCHECK(Bytecodes::IsJumpConstantWide(Bytecodes::FromByte(*jump_location))); | 762 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); |
763 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | |
836 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 764 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; |
837 size_t entry = constant_array_builder()->CommitReservedEntry( | |
838 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); | |
839 DCHECK(FitsInIdx16Operand(entry)); | |
840 uint8_t operand_bytes[2]; | 765 uint8_t operand_bytes[2]; |
841 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); | 766 if (SizeForSignedOperand(delta) <= OperandSize::kShort) { |
767 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort); | |
768 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta)); | |
769 } else { | |
770 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | |
771 *jump_location = Bytecodes::ToByte(jump_bytecode); | |
772 size_t entry = constant_array_builder()->CommitReservedEntry( | |
773 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); | |
774 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); | |
775 } | |
842 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0); | 776 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0); |
843 *operand_location++ = operand_bytes[0]; | 777 *operand_location++ = operand_bytes[0]; |
844 *operand_location = operand_bytes[1]; | 778 *operand_location = operand_bytes[1]; |
845 } | 779 } |
846 | 780 |
781 void BytecodeArrayBuilder::PatchIndirectJumpWith32BitOperand( | |
782 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | |
783 DCHECK(Bytecodes::IsJumpImmediate(Bytecodes::FromByte(*jump_location))); | |
784 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad); | |
785 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | |
786 uint8_t operand_bytes[4]; | |
787 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); | |
788 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0 && | |
789 *(operand_location + 2) == 0 && *(operand_location + 3) == 0); | |
790 *operand_location++ = operand_bytes[0]; | |
791 *operand_location++ = operand_bytes[1]; | |
792 *operand_location++ = operand_bytes[2]; | |
793 *operand_location = operand_bytes[3]; | |
794 } | |
847 | 795 |
848 void BytecodeArrayBuilder::PatchJump( | 796 void BytecodeArrayBuilder::PatchJump( |
849 const ZoneVector<uint8_t>::iterator& jump_target, | 797 const ZoneVector<uint8_t>::iterator& jump_target, |
850 const ZoneVector<uint8_t>::iterator& jump_location) { | 798 const ZoneVector<uint8_t>::iterator& jump_location) { |
799 int delta = static_cast<int>(jump_target - jump_location); | |
851 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | 800 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); |
852 int delta = static_cast<int>(jump_target - jump_location); | 801 int prefix_offset = 0; |
802 OperandScale operand_scale = OperandScale::k1X; | |
803 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) { | |
804 delta -= 1; | |
rmcilroy
2016/03/17 17:30:49
nit - add a comment that this is compensating for
oth
2016/03/21 09:16:53
Done.
| |
805 prefix_offset = 1; | |
806 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode); | |
807 jump_bytecode = Bytecodes::FromByte(*(jump_location + prefix_offset)); | |
808 } | |
809 | |
853 DCHECK(Bytecodes::IsJump(jump_bytecode)); | 810 DCHECK(Bytecodes::IsJump(jump_bytecode)); |
854 switch (Bytecodes::GetOperandSize(jump_bytecode, 0)) { | 811 switch (operand_scale) { |
855 case OperandSize::kByte: | 812 case OperandScale::k1X: |
856 PatchIndirectJumpWith8BitOperand(jump_location, delta); | 813 PatchIndirectJumpWith8BitOperand(jump_location, delta); |
857 break; | 814 break; |
858 case OperandSize::kShort: | 815 case OperandScale::k2X: |
859 PatchIndirectJumpWith16BitOperand(jump_location, delta); | 816 PatchIndirectJumpWith16BitOperand(jump_location + prefix_offset, delta); |
860 break; | 817 break; |
861 case OperandSize::kNone: | 818 case OperandScale::k4X: |
819 PatchIndirectJumpWith32BitOperand(jump_location + prefix_offset, delta); | |
820 break; | |
821 default: | |
862 UNREACHABLE(); | 822 UNREACHABLE(); |
863 } | 823 } |
864 unbound_jumps_--; | 824 unbound_jumps_--; |
865 } | 825 } |
866 | 826 |
867 | 827 |
868 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 828 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
869 BytecodeLabel* label) { | 829 BytecodeLabel* label) { |
870 // Don't emit dead code. | 830 // Don't emit dead code. |
871 if (exit_seen_in_block_) return *this; | 831 if (exit_seen_in_block_) return *this; |
872 | 832 |
873 // Check if the value in accumulator is boolean, if not choose an | 833 // Check if the value in accumulator is boolean, if not choose an |
874 // appropriate JumpIfToBoolean bytecode. | 834 // appropriate JumpIfToBoolean bytecode. |
875 if (NeedToBooleanCast()) { | 835 if (NeedToBooleanCast()) { |
876 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | 836 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
877 } | 837 } |
878 | 838 |
879 if (label->is_bound()) { | 839 if (label->is_bound()) { |
880 // Label has been bound already so this is a backwards jump. | 840 // Label has been bound already so this is a backwards jump. |
881 CHECK_GE(bytecodes()->size(), label->offset()); | 841 CHECK_GE(bytecodes()->size(), label->offset()); |
882 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); | 842 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); |
883 size_t abs_delta = bytecodes()->size() - label->offset(); | 843 size_t abs_delta = bytecodes()->size() - label->offset(); |
884 int delta = -static_cast<int>(abs_delta); | 844 int delta = -static_cast<int>(abs_delta); |
885 | 845 OperandSize operand_size = SizeForSignedOperand(delta); |
886 if (FitsInImm8Operand(delta)) { | 846 if (operand_size > OperandSize::kByte) { |
887 Output(jump_bytecode, static_cast<uint8_t>(delta)); | 847 // Adjust for scaling byte prefix for wide jump offset. |
888 } else { | 848 DCHECK_LE(delta, 0); |
889 size_t entry = | 849 delta -= 1; |
890 GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); | |
891 if (FitsInIdx8Operand(entry)) { | |
892 Output(GetJumpWithConstantOperand(jump_bytecode), | |
893 static_cast<uint8_t>(entry)); | |
894 } else if (FitsInIdx16Operand(entry)) { | |
895 Output(GetJumpWithConstantWideOperand(jump_bytecode), | |
896 static_cast<uint16_t>(entry)); | |
897 } else { | |
898 UNREACHABLE(); | |
899 } | |
900 } | 850 } |
851 OutputScaled(jump_bytecode, OperandSizesToScale(operand_size), | |
852 SignedOperand(delta, operand_size)); | |
901 } else { | 853 } else { |
902 // The label has not yet been bound so this is a forward reference | 854 // The label has not yet been bound so this is a forward reference |
903 // that will be patched when the label is bound. We create a | 855 // that will be patched when the label is bound. We create a |
904 // reservation in the constant pool so the jump can be patched | 856 // reservation in the constant pool so the jump can be patched |
905 // when the label is bound. The reservation means the maximum size | 857 // when the label is bound. The reservation means the maximum size |
906 // of the operand for the constant is known and the jump can | 858 // of the operand for the constant is known and the jump can |
907 // be emitted into the bytecode stream with space for the operand. | 859 // be emitted into the bytecode stream with space for the operand. |
908 label->set_referrer(bytecodes()->size()); | 860 label->set_referrer(bytecodes()->size()); |
909 unbound_jumps_++; | 861 unbound_jumps_++; |
910 OperandSize reserved_operand_size = | 862 OperandSize reserved_operand_size = |
911 constant_array_builder()->CreateReservedEntry(); | 863 constant_array_builder()->CreateReservedEntry(); |
912 switch (reserved_operand_size) { | 864 OutputScaled(jump_bytecode, OperandSizesToScale(reserved_operand_size), 0); |
913 case OperandSize::kByte: | |
914 Output(jump_bytecode, 0); | |
915 break; | |
916 case OperandSize::kShort: | |
917 Output(GetJumpWithConstantWideOperand(jump_bytecode), 0); | |
918 break; | |
919 case OperandSize::kNone: | |
920 UNREACHABLE(); | |
921 } | |
922 } | 865 } |
923 LeaveBasicBlock(); | 866 LeaveBasicBlock(); |
924 return *this; | 867 return *this; |
925 } | 868 } |
926 | 869 |
927 | 870 |
928 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 871 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
929 return OutputJump(Bytecode::kJump, label); | 872 return OutputJump(Bytecode::kJump, label); |
930 } | 873 } |
931 | 874 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
981 return *this; | 924 return *this; |
982 } | 925 } |
983 | 926 |
984 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { | 927 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { |
985 Output(Bytecode::kDebugger); | 928 Output(Bytecode::kDebugger); |
986 return *this; | 929 return *this; |
987 } | 930 } |
988 | 931 |
989 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( | 932 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
990 Register cache_info_triple) { | 933 Register cache_info_triple) { |
991 if (FitsInReg8Operand(cache_info_triple)) { | 934 OperandScale operand_scale = |
992 Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand()); | 935 OperandSizesToScale(SizeForRegisterOperand(cache_info_triple)); |
993 } else if (FitsInReg16Operand(cache_info_triple)) { | 936 OutputScaled(Bytecode::kForInPrepare, operand_scale, |
994 Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand()); | 937 RegisterOperand(cache_info_triple)); |
995 } else { | |
996 UNIMPLEMENTED(); | |
997 } | |
998 return *this; | 938 return *this; |
999 } | 939 } |
1000 | 940 |
1001 | |
1002 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, | 941 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
1003 Register cache_length) { | 942 Register cache_length) { |
1004 Output(Bytecode::kForInDone, index.ToRawOperand(), | 943 OperandScale operand_scale = OperandSizesToScale( |
1005 cache_length.ToRawOperand()); | 944 SizeForRegisterOperand(index), SizeForRegisterOperand(cache_length)); |
945 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), | |
946 RegisterOperand(cache_length)); | |
1006 return *this; | 947 return *this; |
1007 } | 948 } |
1008 | 949 |
1009 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( | 950 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( |
1010 Register receiver, Register index, Register cache_type_array_pair, | 951 Register receiver, Register index, Register cache_type_array_pair, |
1011 int feedback_slot) { | 952 int feedback_slot) { |
1012 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) && | 953 OperandScale operand_scale = OperandSizesToScale( |
1013 FitsInReg8Operand(cache_type_array_pair) && | 954 SizeForRegisterOperand(receiver), SizeForRegisterOperand(index), |
1014 FitsInIdx8Operand(feedback_slot)) { | 955 SizeForRegisterOperand(cache_type_array_pair), |
1015 Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(), | 956 SizeForUnsignedOperand(feedback_slot)); |
1016 cache_type_array_pair.ToRawOperand(), | 957 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), |
1017 static_cast<uint8_t>(feedback_slot)); | 958 RegisterOperand(index), RegisterOperand(cache_type_array_pair), |
1018 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) && | 959 UnsignedOperand(feedback_slot)); |
1019 FitsInReg16Operand(cache_type_array_pair) && | |
1020 FitsInIdx16Operand(feedback_slot)) { | |
1021 Output(Bytecode::kForInNextWide, receiver.ToRawOperand(), | |
1022 index.ToRawOperand(), cache_type_array_pair.ToRawOperand(), | |
1023 static_cast<uint16_t>(feedback_slot)); | |
1024 } else { | |
1025 UNIMPLEMENTED(); | |
1026 } | |
1027 return *this; | 960 return *this; |
1028 } | 961 } |
1029 | 962 |
1030 | 963 |
1031 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { | 964 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
1032 Output(Bytecode::kForInStep, index.ToRawOperand()); | 965 OperandScale operand_scale = |
966 OperandSizesToScale(SizeForRegisterOperand(index)); | |
967 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); | |
1033 return *this; | 968 return *this; |
1034 } | 969 } |
1035 | 970 |
1036 | 971 |
1037 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, | 972 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, |
1038 bool will_catch) { | 973 bool will_catch) { |
1039 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); | 974 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); |
1040 handler_table_builder()->SetPrediction(handler_id, will_catch); | 975 handler_table_builder()->SetPrediction(handler_id, will_catch); |
1041 return *this; | 976 return *this; |
1042 } | 977 } |
(...skipping 25 matching lines...) Expand all Loading... | |
1068 } | 1003 } |
1069 DCHECK(exit_seen_in_block_); | 1004 DCHECK(exit_seen_in_block_); |
1070 } | 1005 } |
1071 | 1006 |
1072 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 1007 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
1073 Register receiver_args, | 1008 Register receiver_args, |
1074 size_t receiver_args_count, | 1009 size_t receiver_args_count, |
1075 int feedback_slot, | 1010 int feedback_slot, |
1076 TailCallMode tail_call_mode) { | 1011 TailCallMode tail_call_mode) { |
1077 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 1012 Bytecode bytecode = BytecodeForCall(tail_call_mode); |
1078 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) && | 1013 OperandScale operand_scale = OperandSizesToScale( |
1079 FitsInIdx8Operand(receiver_args_count) && | 1014 SizeForRegisterOperand(callable), SizeForRegisterOperand(receiver_args), |
1080 FitsInIdx8Operand(feedback_slot)) { | 1015 SizeForUnsignedOperand(receiver_args_count), |
1081 Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(), | 1016 SizeForUnsignedOperand(feedback_slot)); |
1082 static_cast<uint8_t>(receiver_args_count), | 1017 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), |
1083 static_cast<uint8_t>(feedback_slot)); | 1018 RegisterOperand(receiver_args), |
1084 } else if (FitsInReg16Operand(callable) && | 1019 UnsignedOperand(receiver_args_count), |
1085 FitsInReg16Operand(receiver_args) && | 1020 UnsignedOperand(feedback_slot)); |
1086 FitsInIdx16Operand(receiver_args_count) && | |
1087 FitsInIdx16Operand(feedback_slot)) { | |
1088 bytecode = BytecodeForWideOperands(bytecode); | |
1089 Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(), | |
1090 static_cast<uint16_t>(receiver_args_count), | |
1091 static_cast<uint16_t>(feedback_slot)); | |
1092 } else { | |
1093 UNIMPLEMENTED(); | |
1094 } | |
1095 return *this; | 1021 return *this; |
1096 } | 1022 } |
1097 | 1023 |
1098 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 1024 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
1099 Register first_arg, | 1025 Register first_arg, |
1100 size_t arg_count) { | 1026 size_t arg_count) { |
1101 if (!first_arg.is_valid()) { | 1027 if (!first_arg.is_valid()) { |
1102 DCHECK_EQ(0u, arg_count); | 1028 DCHECK_EQ(0u, arg_count); |
1103 first_arg = Register(0); | 1029 first_arg = Register(0); |
1104 } | 1030 } |
1105 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) && | 1031 OperandScale operand_scale = OperandSizesToScale( |
1106 FitsInIdx8Operand(arg_count)) { | 1032 SizeForRegisterOperand(constructor), SizeForRegisterOperand(first_arg), |
1107 Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(), | 1033 SizeForUnsignedOperand(arg_count)); |
1108 static_cast<uint8_t>(arg_count)); | 1034 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), |
1109 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) && | 1035 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
1110 FitsInIdx16Operand(arg_count)) { | |
1111 Output(Bytecode::kNewWide, constructor.ToRawOperand(), | |
1112 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
1113 } else { | |
1114 UNIMPLEMENTED(); | |
1115 } | |
1116 return *this; | 1036 return *this; |
1117 } | 1037 } |
1118 | 1038 |
1119 | 1039 |
1120 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 1040 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
1121 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 1041 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
1122 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); | 1042 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
1123 DCHECK(FitsInIdx16Operand(function_id)); | 1043 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
1124 if (!first_arg.is_valid()) { | 1044 if (!first_arg.is_valid()) { |
1125 DCHECK_EQ(0u, arg_count); | 1045 DCHECK_EQ(0u, arg_count); |
1126 first_arg = Register(0); | 1046 first_arg = Register(0); |
1127 } | 1047 } |
1128 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) { | 1048 OperandScale operand_scale = OperandSizesToScale( |
1129 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), | 1049 SizeForRegisterOperand(first_arg), SizeForUnsignedOperand(arg_count)); |
1130 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count)); | 1050 OutputScaled(Bytecode::kCallRuntime, operand_scale, |
1131 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) { | 1051 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), |
1132 Output(Bytecode::kCallRuntimeWide, static_cast<uint16_t>(function_id), | 1052 UnsignedOperand(arg_count)); |
1133 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count)); | |
1134 } else { | |
1135 UNIMPLEMENTED(); | |
1136 } | |
1137 return *this; | 1053 return *this; |
1138 } | 1054 } |
1139 | 1055 |
1140 | 1056 |
1141 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( | 1057 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
1142 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, | 1058 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
1143 Register first_return) { | 1059 Register first_return) { |
1144 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); | 1060 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
1145 DCHECK(FitsInIdx16Operand(function_id)); | 1061 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
1146 if (!first_arg.is_valid()) { | 1062 if (!first_arg.is_valid()) { |
1147 DCHECK_EQ(0u, arg_count); | 1063 DCHECK_EQ(0u, arg_count); |
1148 first_arg = Register(0); | 1064 first_arg = Register(0); |
1149 } | 1065 } |
1150 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) && | 1066 OperandScale operand_scale = OperandSizesToScale( |
1151 FitsInReg8Operand(first_return)) { | 1067 SizeForRegisterOperand(first_arg), SizeForUnsignedOperand(arg_count), |
1152 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), | 1068 SizeForRegisterOperand(first_return)); |
1153 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count), | 1069 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, |
1154 first_return.ToRawOperand()); | 1070 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), |
1155 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) && | 1071 UnsignedOperand(arg_count), RegisterOperand(first_return)); |
1156 FitsInReg16Operand(first_return)) { | |
1157 Output(Bytecode::kCallRuntimeForPairWide, | |
1158 static_cast<uint16_t>(function_id), first_arg.ToRawOperand(), | |
1159 static_cast<uint16_t>(arg_count), first_return.ToRawOperand()); | |
1160 } else { | |
1161 UNIMPLEMENTED(); | |
1162 } | |
1163 return *this; | 1072 return *this; |
1164 } | 1073 } |
1165 | 1074 |
1166 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 1075 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
1167 int context_index, Register receiver_args, size_t receiver_args_count) { | 1076 int context_index, Register receiver_args, size_t receiver_args_count) { |
1168 DCHECK(FitsInIdx16Operand(context_index)); | 1077 OperandScale operand_scale = |
1169 if (FitsInReg8Operand(receiver_args) && | 1078 OperandSizesToScale(SizeForUnsignedOperand(context_index), |
1170 FitsInIdx8Operand(receiver_args_count)) { | 1079 SizeForRegisterOperand(receiver_args), |
1171 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), | 1080 SizeForUnsignedOperand(receiver_args_count)); |
1172 receiver_args.ToRawOperand(), | 1081 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, |
1173 static_cast<uint8_t>(receiver_args_count)); | 1082 UnsignedOperand(context_index), RegisterOperand(receiver_args), |
1174 } else if (FitsInReg16Operand(receiver_args) && | 1083 UnsignedOperand(receiver_args_count)); |
1175 FitsInIdx16Operand(receiver_args_count)) { | |
1176 Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index), | |
1177 receiver_args.ToRawOperand(), | |
1178 static_cast<uint16_t>(receiver_args_count)); | |
1179 } else { | |
1180 UNIMPLEMENTED(); | |
1181 } | |
1182 return *this; | 1084 return *this; |
1183 } | 1085 } |
1184 | 1086 |
1185 | 1087 |
1186 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 1088 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
1187 LanguageMode language_mode) { | 1089 LanguageMode language_mode) { |
1188 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); | 1090 OperandScale operand_scale = |
1091 OperandSizesToScale(SizeForRegisterOperand(object)); | |
1092 OutputScaled(BytecodeForDelete(language_mode), operand_scale, | |
1093 RegisterOperand(object)); | |
1189 return *this; | 1094 return *this; |
1190 } | 1095 } |
1191 | 1096 |
1192 | |
1193 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 1097 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
1194 return constant_array_builder()->Insert(object); | 1098 return constant_array_builder()->Insert(object); |
1195 } | 1099 } |
1196 | 1100 |
1197 void BytecodeArrayBuilder::SetReturnPosition() { | 1101 void BytecodeArrayBuilder::SetReturnPosition() { |
1198 if (return_position_ == RelocInfo::kNoPosition) return; | 1102 if (return_position_ == RelocInfo::kNoPosition) return; |
1199 if (exit_seen_in_block_) return; | 1103 if (exit_seen_in_block_) return; |
1200 source_position_table_builder_.AddStatementPosition( | 1104 source_position_table_builder_.AddStatementPosition( |
1201 bytecodes_.size(), return_position_, | 1105 bytecodes_.size(), return_position_, |
1202 SourcePositionTableBuilder::OVERWRITE_DUPLICATE); | 1106 SourcePositionTableBuilder::OVERWRITE_DUPLICATE); |
(...skipping 17 matching lines...) Expand all Loading... | |
1220 if (expr->position() == RelocInfo::kNoPosition) return; | 1124 if (expr->position() == RelocInfo::kNoPosition) return; |
1221 if (exit_seen_in_block_) return; | 1125 if (exit_seen_in_block_) return; |
1222 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 1126 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), |
1223 expr->position()); | 1127 expr->position()); |
1224 } | 1128 } |
1225 | 1129 |
1226 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 1130 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
1227 return temporary_register_allocator()->RegisterIsLive(reg); | 1131 return temporary_register_allocator()->RegisterIsLive(reg); |
1228 } | 1132 } |
1229 | 1133 |
1230 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 1134 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, |
1135 OperandScale operand_scale, | |
1136 int operand_index, | |
1231 uint32_t operand_value) const { | 1137 uint32_t operand_value) const { |
1138 OperandSize operand_size = | |
1139 Bytecodes::GetOperandSize(bytecode, operand_index, operand_scale); | |
1232 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 1140 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
1233 switch (operand_type) { | 1141 switch (operand_type) { |
1234 case OperandType::kNone: | 1142 case OperandType::kNone: |
1235 return false; | 1143 return false; |
1236 case OperandType::kRegCount16: { | 1144 case OperandType::kRegCount: { |
1237 // Expect kRegCount16 is part of a range previous operand is a | |
1238 // valid operand to start a range. | |
1239 if (operand_index > 0) { | 1145 if (operand_index > 0) { |
1240 OperandType previous_operand_type = | 1146 OperandType previous_operand_type = |
1241 Bytecodes::GetOperandType(bytecode, operand_index - 1); | 1147 Bytecodes::GetOperandType(bytecode, operand_index - 1); |
1242 return ((previous_operand_type == OperandType::kMaybeReg16 || | 1148 if (previous_operand_type != OperandType::kMaybeReg && |
1243 previous_operand_type == OperandType::kReg16) && | 1149 previous_operand_type != OperandType::kReg) { |
1244 static_cast<uint16_t>(operand_value) == operand_value); | 1150 return false; |
1245 } else { | 1151 } |
1246 return false; | |
1247 } | 1152 } |
1153 } // Fall-through | |
1154 case OperandType::kFlag8: | |
1155 case OperandType::kIdx: | |
1156 case OperandType::kRuntimeId: | |
1157 case OperandType::kImm: { | |
1158 size_t unsigned_value = static_cast<size_t>(operand_value); | |
1159 return SizeForUnsignedOperand(unsigned_value) <= operand_size; | |
1248 } | 1160 } |
1249 case OperandType::kRegCount8: { | 1161 case OperandType::kMaybeReg: |
1250 // Expect kRegCount8 is part of a range previous operand is a | |
1251 // valid operand to start a range. | |
1252 if (operand_index > 0) { | |
1253 OperandType previous_operand_type = | |
1254 Bytecodes::GetOperandType(bytecode, operand_index - 1); | |
1255 return ((previous_operand_type == OperandType::kMaybeReg8 || | |
1256 previous_operand_type == OperandType::kReg8 || | |
1257 previous_operand_type == OperandType::kMaybeReg16) && | |
1258 static_cast<uint8_t>(operand_value) == operand_value); | |
1259 } else { | |
1260 return false; | |
1261 } | |
1262 } | |
1263 case OperandType::kIdx16: | |
1264 return static_cast<uint16_t>(operand_value) == operand_value; | |
1265 case OperandType::kImm8: | |
1266 case OperandType::kIdx8: | |
1267 return static_cast<uint8_t>(operand_value) == operand_value; | |
1268 case OperandType::kMaybeReg8: | |
1269 if (operand_value == 0) { | 1162 if (operand_value == 0) { |
1270 return true; | 1163 return true; |
1271 } | 1164 } |
1272 // Fall-through to kReg8 case. | 1165 // Fall-through to kReg case. |
1273 case OperandType::kReg8: | 1166 case OperandType::kReg: |
1274 case OperandType::kRegOut8: | 1167 case OperandType::kRegOut: { |
1275 return RegisterIsValid(Register::FromRawOperand(operand_value), | 1168 Register reg = RegisterFromOperand(operand_value); |
1276 operand_type); | 1169 return RegisterIsValid(reg, operand_size); |
1277 case OperandType::kRegOutPair8: | 1170 } |
1278 case OperandType::kRegOutPair16: | 1171 case OperandType::kRegOutPair: |
1279 case OperandType::kRegPair8: | 1172 case OperandType::kRegPair: { |
1280 case OperandType::kRegPair16: { | 1173 Register reg0 = RegisterFromOperand(operand_value); |
1281 Register reg0 = Register::FromRawOperand(operand_value); | |
1282 Register reg1 = Register(reg0.index() + 1); | 1174 Register reg1 = Register(reg0.index() + 1); |
1283 return RegisterIsValid(reg0, operand_type) && | 1175 // The size of reg1 is immaterial. |
1284 RegisterIsValid(reg1, operand_type); | 1176 return RegisterIsValid(reg0, operand_size) && |
1177 RegisterIsValid(reg1, OperandSize::kQuad); | |
1285 } | 1178 } |
1286 case OperandType::kRegOutTriple8: | 1179 case OperandType::kRegOutTriple: { |
1287 case OperandType::kRegOutTriple16: { | 1180 Register reg0 = RegisterFromOperand(operand_value); |
1288 Register reg0 = Register::FromRawOperand(operand_value); | |
1289 Register reg1 = Register(reg0.index() + 1); | 1181 Register reg1 = Register(reg0.index() + 1); |
1290 Register reg2 = Register(reg0.index() + 2); | 1182 Register reg2 = Register(reg0.index() + 2); |
1291 return RegisterIsValid(reg0, operand_type) && | 1183 // The size of reg1 and reg2 is immaterial. |
1292 RegisterIsValid(reg1, operand_type) && | 1184 return RegisterIsValid(reg0, operand_size) && |
1293 RegisterIsValid(reg2, operand_type); | 1185 RegisterIsValid(reg1, OperandSize::kQuad) && |
1294 } | 1186 RegisterIsValid(reg2, OperandSize::kQuad); |
1295 case OperandType::kMaybeReg16: | |
1296 if (operand_value == 0) { | |
1297 return true; | |
1298 } | |
1299 // Fall-through to kReg16 case. | |
1300 case OperandType::kReg16: | |
1301 case OperandType::kRegOut16: { | |
1302 Register reg = Register::FromRawOperand(operand_value); | |
1303 return RegisterIsValid(reg, operand_type); | |
1304 } | 1187 } |
1305 } | 1188 } |
1306 UNREACHABLE(); | 1189 UNREACHABLE(); |
1307 return false; | 1190 return false; |
1308 } | 1191 } |
1309 | 1192 |
1310 | |
1311 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, | 1193 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, |
1312 OperandType reg_type) const { | 1194 OperandSize reg_size) const { |
1313 if (!reg.is_valid()) { | 1195 if (!reg.is_valid()) { |
1314 return false; | 1196 return false; |
1315 } | 1197 } |
1316 | 1198 |
1317 switch (Bytecodes::SizeOfOperand(reg_type)) { | 1199 if (SizeForRegisterOperand(reg) > reg_size) { |
1318 case OperandSize::kByte: | 1200 return false; |
1319 if (!FitsInReg8OperandUntranslated(reg)) { | |
1320 return false; | |
1321 } | |
1322 break; | |
1323 case OperandSize::kShort: | |
1324 if (!FitsInReg16OperandUntranslated(reg)) { | |
1325 return false; | |
1326 } | |
1327 break; | |
1328 case OperandSize::kNone: | |
1329 UNREACHABLE(); | |
1330 return false; | |
1331 } | 1201 } |
1332 | 1202 |
1333 if (reg.is_current_context() || reg.is_function_closure() || | 1203 if (reg.is_current_context() || reg.is_function_closure() || |
1334 reg.is_new_target()) { | 1204 reg.is_new_target()) { |
1335 return true; | 1205 return true; |
1336 } else if (reg.is_parameter()) { | 1206 } else if (reg.is_parameter()) { |
1337 int parameter_index = reg.ToParameterIndex(parameter_count()); | 1207 int parameter_index = reg.ToParameterIndex(parameter_count()); |
1338 return parameter_index >= 0 && parameter_index < parameter_count(); | 1208 return parameter_index >= 0 && parameter_index < parameter_count(); |
1339 } else if (RegisterTranslator::InTranslationWindow(reg)) { | 1209 } else if (reg.index() < fixed_register_count()) { |
1340 return translation_register_count() > 0; | 1210 return true; |
1341 } else { | 1211 } else { |
1342 reg = RegisterTranslator::UntranslateRegister(reg); | 1212 return TemporaryRegisterIsLive(reg); |
1343 if (reg.index() < fixed_register_count()) { | |
1344 return true; | |
1345 } else { | |
1346 return TemporaryRegisterIsLive(reg); | |
1347 } | |
1348 } | 1213 } |
1349 } | 1214 } |
1350 | 1215 |
1351 | 1216 |
1352 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | 1217 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { |
1353 return last_bytecode_start_ < bytecodes()->size() && | 1218 return last_bytecode_start_ < bytecodes()->size() && |
1354 last_bytecode_start_ >= last_block_end_; | 1219 last_bytecode_start_ >= last_block_end_; |
1355 } | 1220 } |
1356 | 1221 |
1357 | 1222 |
1358 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { | 1223 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { |
1359 if (LastBytecodeInSameBlock()) { | 1224 if (LastBytecodeInSameBlock()) { |
1360 PreviousBytecodeHelper previous_bytecode(*this); | 1225 PreviousBytecodeHelper previous_bytecode(*this); |
1361 Bytecode bytecode = previous_bytecode.GetBytecode(); | 1226 Bytecode bytecode = previous_bytecode.GetBytecode(); |
1362 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) { | 1227 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) { |
1363 Register previous_reg = | 1228 return previous_bytecode.GetRegisterOperand(0) == reg; |
1364 Register::FromOperand(previous_bytecode.GetOperand(0)); | |
1365 return previous_reg == reg; | |
1366 } | 1229 } |
1367 } | 1230 } |
1368 return false; | 1231 return false; |
1369 } | 1232 } |
1370 | 1233 |
1371 | 1234 |
1372 // static | 1235 // static |
1373 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 1236 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
1374 switch (op) { | 1237 switch (op) { |
1375 case Token::Value::ADD: | 1238 case Token::Value::ADD: |
(...skipping 13 matching lines...) Expand all Loading... | |
1389 case Token::Value::BIT_AND: | 1252 case Token::Value::BIT_AND: |
1390 return Bytecode::kBitwiseAnd; | 1253 return Bytecode::kBitwiseAnd; |
1391 case Token::Value::SHL: | 1254 case Token::Value::SHL: |
1392 return Bytecode::kShiftLeft; | 1255 return Bytecode::kShiftLeft; |
1393 case Token::Value::SAR: | 1256 case Token::Value::SAR: |
1394 return Bytecode::kShiftRight; | 1257 return Bytecode::kShiftRight; |
1395 case Token::Value::SHR: | 1258 case Token::Value::SHR: |
1396 return Bytecode::kShiftRightLogical; | 1259 return Bytecode::kShiftRightLogical; |
1397 default: | 1260 default: |
1398 UNREACHABLE(); | 1261 UNREACHABLE(); |
1399 return static_cast<Bytecode>(-1); | 1262 return Bytecode::kIllegal; |
1400 } | 1263 } |
1401 } | 1264 } |
1402 | 1265 |
1403 | 1266 |
1404 // static | 1267 // static |
1405 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) { | 1268 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) { |
1406 switch (op) { | 1269 switch (op) { |
1407 case Token::Value::ADD: | 1270 case Token::Value::ADD: |
1408 return Bytecode::kInc; | 1271 return Bytecode::kInc; |
1409 case Token::Value::SUB: | 1272 case Token::Value::SUB: |
1410 return Bytecode::kDec; | 1273 return Bytecode::kDec; |
1411 default: | 1274 default: |
1412 UNREACHABLE(); | 1275 UNREACHABLE(); |
1413 return static_cast<Bytecode>(-1); | 1276 return Bytecode::kIllegal; |
1414 } | 1277 } |
1415 } | 1278 } |
1416 | 1279 |
1417 | 1280 |
1418 // static | 1281 // static |
1419 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { | 1282 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { |
1420 switch (op) { | 1283 switch (op) { |
1421 case Token::Value::EQ: | 1284 case Token::Value::EQ: |
1422 return Bytecode::kTestEqual; | 1285 return Bytecode::kTestEqual; |
1423 case Token::Value::NE: | 1286 case Token::Value::NE: |
1424 return Bytecode::kTestNotEqual; | 1287 return Bytecode::kTestNotEqual; |
1425 case Token::Value::EQ_STRICT: | 1288 case Token::Value::EQ_STRICT: |
1426 return Bytecode::kTestEqualStrict; | 1289 return Bytecode::kTestEqualStrict; |
1427 case Token::Value::LT: | 1290 case Token::Value::LT: |
1428 return Bytecode::kTestLessThan; | 1291 return Bytecode::kTestLessThan; |
1429 case Token::Value::GT: | 1292 case Token::Value::GT: |
1430 return Bytecode::kTestGreaterThan; | 1293 return Bytecode::kTestGreaterThan; |
1431 case Token::Value::LTE: | 1294 case Token::Value::LTE: |
1432 return Bytecode::kTestLessThanOrEqual; | 1295 return Bytecode::kTestLessThanOrEqual; |
1433 case Token::Value::GTE: | 1296 case Token::Value::GTE: |
1434 return Bytecode::kTestGreaterThanOrEqual; | 1297 return Bytecode::kTestGreaterThanOrEqual; |
1435 case Token::Value::INSTANCEOF: | 1298 case Token::Value::INSTANCEOF: |
1436 return Bytecode::kTestInstanceOf; | 1299 return Bytecode::kTestInstanceOf; |
1437 case Token::Value::IN: | 1300 case Token::Value::IN: |
1438 return Bytecode::kTestIn; | 1301 return Bytecode::kTestIn; |
1439 default: | 1302 default: |
1440 UNREACHABLE(); | 1303 UNREACHABLE(); |
1441 return static_cast<Bytecode>(-1); | 1304 return Bytecode::kIllegal; |
1442 } | 1305 } |
1443 } | 1306 } |
1444 | 1307 |
1445 | |
1446 // static | |
1447 Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) { | |
1448 switch (bytecode) { | |
1449 case Bytecode::kCall: | |
1450 return Bytecode::kCallWide; | |
1451 case Bytecode::kTailCall: | |
1452 return Bytecode::kTailCallWide; | |
1453 case Bytecode::kLoadIC: | |
1454 return Bytecode::kLoadICWide; | |
1455 case Bytecode::kKeyedLoadIC: | |
1456 return Bytecode::kKeyedLoadICWide; | |
1457 case Bytecode::kStoreICSloppy: | |
1458 return Bytecode::kStoreICSloppyWide; | |
1459 case Bytecode::kStoreICStrict: | |
1460 return Bytecode::kStoreICStrictWide; | |
1461 case Bytecode::kKeyedStoreICSloppy: | |
1462 return Bytecode::kKeyedStoreICSloppyWide; | |
1463 case Bytecode::kKeyedStoreICStrict: | |
1464 return Bytecode::kKeyedStoreICStrictWide; | |
1465 case Bytecode::kLdaGlobal: | |
1466 return Bytecode::kLdaGlobalWide; | |
1467 case Bytecode::kLdaGlobalInsideTypeof: | |
1468 return Bytecode::kLdaGlobalInsideTypeofWide; | |
1469 case Bytecode::kStaGlobalSloppy: | |
1470 return Bytecode::kStaGlobalSloppyWide; | |
1471 case Bytecode::kStaGlobalStrict: | |
1472 return Bytecode::kStaGlobalStrictWide; | |
1473 case Bytecode::kLdaLookupSlot: | |
1474 return Bytecode::kLdaLookupSlotWide; | |
1475 case Bytecode::kLdaLookupSlotInsideTypeof: | |
1476 return Bytecode::kLdaLookupSlotInsideTypeofWide; | |
1477 case Bytecode::kStaLookupSlotStrict: | |
1478 return Bytecode::kStaLookupSlotStrictWide; | |
1479 case Bytecode::kStaLookupSlotSloppy: | |
1480 return Bytecode::kStaLookupSlotSloppyWide; | |
1481 default: | |
1482 UNREACHABLE(); | |
1483 return static_cast<Bytecode>(-1); | |
1484 } | |
1485 } | |
1486 | |
1487 | 1308 |
1488 // static | 1309 // static |
1489 Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) { | 1310 Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) { |
1490 switch (language_mode) { | 1311 switch (language_mode) { |
1491 case SLOPPY: | 1312 case SLOPPY: |
1492 return Bytecode::kStoreICSloppy; | 1313 return Bytecode::kStoreICSloppy; |
1493 case STRICT: | 1314 case STRICT: |
1494 return Bytecode::kStoreICStrict; | 1315 return Bytecode::kStoreICStrict; |
1495 default: | 1316 default: |
1496 UNREACHABLE(); | 1317 UNREACHABLE(); |
1497 } | 1318 } |
1498 return static_cast<Bytecode>(-1); | 1319 return Bytecode::kIllegal; |
1499 } | 1320 } |
1500 | 1321 |
1501 | 1322 |
1502 // static | 1323 // static |
1503 Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC( | 1324 Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC( |
1504 LanguageMode language_mode) { | 1325 LanguageMode language_mode) { |
1505 switch (language_mode) { | 1326 switch (language_mode) { |
1506 case SLOPPY: | 1327 case SLOPPY: |
1507 return Bytecode::kKeyedStoreICSloppy; | 1328 return Bytecode::kKeyedStoreICSloppy; |
1508 case STRICT: | 1329 case STRICT: |
1509 return Bytecode::kKeyedStoreICStrict; | 1330 return Bytecode::kKeyedStoreICStrict; |
1510 default: | 1331 default: |
1511 UNREACHABLE(); | 1332 UNREACHABLE(); |
1512 } | 1333 } |
1513 return static_cast<Bytecode>(-1); | 1334 return Bytecode::kIllegal; |
1514 } | 1335 } |
1515 | 1336 |
1516 | 1337 |
1517 // static | 1338 // static |
1518 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { | 1339 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { |
1519 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof | 1340 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof |
1520 : Bytecode::kLdaGlobal; | 1341 : Bytecode::kLdaGlobal; |
1521 } | 1342 } |
1522 | 1343 |
1523 | 1344 |
1524 // static | 1345 // static |
1525 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( | 1346 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( |
1526 LanguageMode language_mode) { | 1347 LanguageMode language_mode) { |
1527 switch (language_mode) { | 1348 switch (language_mode) { |
1528 case SLOPPY: | 1349 case SLOPPY: |
1529 return Bytecode::kStaGlobalSloppy; | 1350 return Bytecode::kStaGlobalSloppy; |
1530 case STRICT: | 1351 case STRICT: |
1531 return Bytecode::kStaGlobalStrict; | 1352 return Bytecode::kStaGlobalStrict; |
1532 default: | 1353 default: |
1533 UNREACHABLE(); | 1354 UNREACHABLE(); |
1534 } | 1355 } |
1535 return static_cast<Bytecode>(-1); | 1356 return Bytecode::kIllegal; |
1536 } | 1357 } |
1537 | 1358 |
1538 | 1359 |
1539 // static | 1360 // static |
1540 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( | 1361 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( |
1541 LanguageMode language_mode) { | 1362 LanguageMode language_mode) { |
1542 switch (language_mode) { | 1363 switch (language_mode) { |
1543 case SLOPPY: | 1364 case SLOPPY: |
1544 return Bytecode::kStaLookupSlotSloppy; | 1365 return Bytecode::kStaLookupSlotSloppy; |
1545 case STRICT: | 1366 case STRICT: |
1546 return Bytecode::kStaLookupSlotStrict; | 1367 return Bytecode::kStaLookupSlotStrict; |
1547 default: | 1368 default: |
1548 UNREACHABLE(); | 1369 UNREACHABLE(); |
1549 } | 1370 } |
1550 return static_cast<Bytecode>(-1); | 1371 return Bytecode::kIllegal; |
1551 } | 1372 } |
1552 | 1373 |
1553 // static | 1374 // static |
1554 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( | 1375 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( |
1555 CreateArgumentsType type) { | 1376 CreateArgumentsType type) { |
1556 switch (type) { | 1377 switch (type) { |
1557 case CreateArgumentsType::kMappedArguments: | 1378 case CreateArgumentsType::kMappedArguments: |
1558 return Bytecode::kCreateMappedArguments; | 1379 return Bytecode::kCreateMappedArguments; |
1559 case CreateArgumentsType::kUnmappedArguments: | 1380 case CreateArgumentsType::kUnmappedArguments: |
1560 return Bytecode::kCreateUnmappedArguments; | 1381 return Bytecode::kCreateUnmappedArguments; |
1561 case CreateArgumentsType::kRestParameter: | 1382 case CreateArgumentsType::kRestParameter: |
1562 return Bytecode::kCreateRestParameter; | 1383 return Bytecode::kCreateRestParameter; |
1563 } | 1384 } |
1564 UNREACHABLE(); | 1385 UNREACHABLE(); |
1565 return static_cast<Bytecode>(-1); | 1386 return Bytecode::kIllegal; |
1566 } | 1387 } |
1567 | 1388 |
1568 | 1389 |
1569 // static | 1390 // static |
1570 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { | 1391 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { |
1571 switch (language_mode) { | 1392 switch (language_mode) { |
1572 case SLOPPY: | 1393 case SLOPPY: |
1573 return Bytecode::kDeletePropertySloppy; | 1394 return Bytecode::kDeletePropertySloppy; |
1574 case STRICT: | 1395 case STRICT: |
1575 return Bytecode::kDeletePropertyStrict; | 1396 return Bytecode::kDeletePropertyStrict; |
1576 default: | 1397 default: |
1577 UNREACHABLE(); | 1398 UNREACHABLE(); |
1578 } | 1399 } |
1579 return static_cast<Bytecode>(-1); | 1400 return Bytecode::kIllegal; |
1580 } | 1401 } |
1581 | 1402 |
1582 // static | 1403 // static |
1583 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) { | 1404 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) { |
1584 switch (tail_call_mode) { | 1405 switch (tail_call_mode) { |
1585 case TailCallMode::kDisallow: | 1406 case TailCallMode::kDisallow: |
1586 return Bytecode::kCall; | 1407 return Bytecode::kCall; |
1587 case TailCallMode::kAllow: | 1408 case TailCallMode::kAllow: |
1588 return Bytecode::kTailCall; | 1409 return Bytecode::kTailCall; |
1589 default: | 1410 default: |
1590 UNREACHABLE(); | 1411 UNREACHABLE(); |
1591 } | 1412 } |
1592 return static_cast<Bytecode>(-1); | 1413 return Bytecode::kIllegal; |
1593 } | 1414 } |
1594 | 1415 |
1595 // static | 1416 // static |
1596 bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) { | 1417 OperandSize BytecodeArrayBuilder::SizeForRegisterOperand(Register value) { |
1597 return kMinUInt8 <= value && value <= kMaxUInt8; | 1418 if (value.is_byte_operand()) { |
1598 } | 1419 return OperandSize::kByte; |
1599 | 1420 } else if (value.is_short_operand()) { |
1600 | 1421 return OperandSize::kShort; |
1601 // static | 1422 } else { |
1602 bool BytecodeArrayBuilder::FitsInIdx8Operand(size_t value) { | 1423 return OperandSize::kQuad; |
1603 return value <= static_cast<size_t>(kMaxUInt8); | 1424 } |
1604 } | |
1605 | |
1606 | |
1607 // static | |
1608 bool BytecodeArrayBuilder::FitsInImm8Operand(int value) { | |
1609 return kMinInt8 <= value && value <= kMaxInt8; | |
1610 } | |
1611 | |
1612 | |
1613 // static | |
1614 bool BytecodeArrayBuilder::FitsInIdx16Operand(int value) { | |
1615 return kMinUInt16 <= value && value <= kMaxUInt16; | |
1616 } | |
1617 | |
1618 | |
1619 // static | |
1620 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) { | |
1621 return value <= static_cast<size_t>(kMaxUInt16); | |
1622 } | |
1623 | |
1624 | |
1625 // static | |
1626 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) { | |
1627 return RegisterTranslator::FitsInReg8Operand(value); | |
1628 } | 1425 } |
1629 | 1426 |
1630 // static | 1427 // static |
1631 bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) { | 1428 OperandSize BytecodeArrayBuilder::SizeForSignedOperand(int value) { |
1632 return value.is_byte_operand(); | 1429 if (kMinInt8 <= value && value <= kMaxInt8) { |
1633 } | 1430 return OperandSize::kByte; |
1634 | 1431 } else if (kMinInt16 <= value && value <= kMaxInt16) { |
1635 | 1432 return OperandSize::kShort; |
1636 // static | 1433 } else { |
1637 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { | 1434 return OperandSize::kQuad; |
1638 return RegisterTranslator::FitsInReg16Operand(value); | 1435 } |
1639 } | 1436 } |
1640 | 1437 |
1641 // static | 1438 // static |
1642 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { | 1439 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(int value) { |
1643 return value.is_short_operand(); | 1440 DCHECK_GE(value, 0); |
1441 if (value <= kMaxUInt8) { | |
1442 return OperandSize::kByte; | |
1443 } else if (value <= kMaxUInt16) { | |
1444 return OperandSize::kShort; | |
1445 } else { | |
1446 return OperandSize::kQuad; | |
1447 } | |
1448 } | |
1449 | |
1450 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(size_t value) { | |
1451 if (value <= static_cast<size_t>(kMaxUInt8)) { | |
1452 return OperandSize::kByte; | |
1453 } else if (value <= static_cast<size_t>(kMaxUInt16)) { | |
1454 return OperandSize::kShort; | |
1455 } else if (value <= kMaxUInt32) { | |
1456 return OperandSize::kQuad; | |
1457 } else { | |
1458 UNREACHABLE(); | |
1459 return OperandSize::kQuad; | |
1460 } | |
1461 } | |
1462 | |
1463 OperandScale BytecodeArrayBuilder::OperandSizesToScale(OperandSize size0, | |
1464 OperandSize size1, | |
1465 OperandSize size2, | |
1466 OperandSize size3) { | |
1467 OperandSize upper = std::max(size0, size1); | |
1468 OperandSize lower = std::max(size2, size3); | |
1469 OperandSize result = std::max(upper, lower); | |
1470 OperandScale operand_scale = static_cast<OperandScale>(result); | |
rmcilroy
2016/03/17 17:30:49
Could you add a STATIC_ASSERT that casting Operand
oth
2016/03/21 09:16:53
Done.
| |
1471 DCHECK(operand_scale == OperandScale::k1X || | |
1472 operand_scale == OperandScale::k2X || | |
1473 operand_scale == OperandScale::k4X); | |
1474 return operand_scale; | |
1475 } | |
1476 | |
1477 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { | |
1478 return static_cast<uint32_t>(reg.ToOperand()); | |
rmcilroy
2016/03/17 17:30:49
Could we just make reg.ToOperand return a uint32_t
oth
2016/03/21 09:16:53
Probably being overly conservative here but would
| |
1479 } | |
1480 | |
1481 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { | |
1482 return Register::FromOperand(static_cast<int32_t>(operand)); | |
1483 } | |
1484 | |
1485 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { | |
1486 switch (size) { | |
1487 case OperandSize::kByte: | |
1488 return static_cast<uint8_t>(value & 0xff); | |
1489 case OperandSize::kShort: | |
1490 return static_cast<uint16_t>(value & 0xffff); | |
1491 case OperandSize::kQuad: | |
1492 return static_cast<uint32_t>(value); | |
1493 case OperandSize::kNone: | |
1494 UNREACHABLE(); | |
1495 } | |
1496 return 0; | |
1497 } | |
1498 | |
1499 uint32_t BytecodeArrayBuilder::UnsignedOperand(int value) { | |
1500 DCHECK_GE(value, 0); | |
1501 return static_cast<uint32_t>(value); | |
1502 } | |
1503 | |
1504 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { | |
1505 DCHECK_LE(value, kMaxUInt32); | |
1506 return static_cast<uint32_t>(value); | |
1644 } | 1507 } |
1645 | 1508 |
1646 } // namespace interpreter | 1509 } // namespace interpreter |
1647 } // namespace internal | 1510 } // namespace internal |
1648 } // namespace v8 | 1511 } // namespace v8 |
OLD | NEW |