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