Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Re-generate golden files. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 DCHECK(!FLAG_harmony_instanceof); 1280 DCHECK(!FLAG_harmony_instanceof);
1437 return Bytecode::kTestInstanceOf; 1281 return Bytecode::kTestInstanceOf;
1438 case Token::Value::IN: 1282 case Token::Value::IN:
1439 return Bytecode::kTestIn; 1283 return Bytecode::kTestIn;
1440 default: 1284 default:
1441 UNREACHABLE(); 1285 UNREACHABLE();
1442 return static_cast<Bytecode>(-1); 1286 return Bytecode::kIllegal;
1443 } 1287 }
1444 } 1288 }
1445 1289
1446
1447 // static
1448 Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
1449 switch (bytecode) {
1450 case Bytecode::kCall:
1451 return Bytecode::kCallWide;
1452 case Bytecode::kTailCall:
1453 return Bytecode::kTailCallWide;
1454 case Bytecode::kLoadIC:
1455 return Bytecode::kLoadICWide;
1456 case Bytecode::kKeyedLoadIC:
1457 return Bytecode::kKeyedLoadICWide;
1458 case Bytecode::kStoreICSloppy:
1459 return Bytecode::kStoreICSloppyWide;
1460 case Bytecode::kStoreICStrict:
1461 return Bytecode::kStoreICStrictWide;
1462 case Bytecode::kKeyedStoreICSloppy:
1463 return Bytecode::kKeyedStoreICSloppyWide;
1464 case Bytecode::kKeyedStoreICStrict:
1465 return Bytecode::kKeyedStoreICStrictWide;
1466 case Bytecode::kLdaGlobal:
1467 return Bytecode::kLdaGlobalWide;
1468 case Bytecode::kLdaGlobalInsideTypeof:
1469 return Bytecode::kLdaGlobalInsideTypeofWide;
1470 case Bytecode::kStaGlobalSloppy:
1471 return Bytecode::kStaGlobalSloppyWide;
1472 case Bytecode::kStaGlobalStrict:
1473 return Bytecode::kStaGlobalStrictWide;
1474 case Bytecode::kLdaLookupSlot:
1475 return Bytecode::kLdaLookupSlotWide;
1476 case Bytecode::kLdaLookupSlotInsideTypeof:
1477 return Bytecode::kLdaLookupSlotInsideTypeofWide;
1478 case Bytecode::kStaLookupSlotStrict:
1479 return Bytecode::kStaLookupSlotStrictWide;
1480 case Bytecode::kStaLookupSlotSloppy:
1481 return Bytecode::kStaLookupSlotSloppyWide;
1482 default:
1483 UNREACHABLE();
1484 return static_cast<Bytecode>(-1);
1485 }
1486 }
1487
1488 1290
1489 // static 1291 // static
1490 Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) { 1292 Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) {
1491 switch (language_mode) { 1293 switch (language_mode) {
1492 case SLOPPY: 1294 case SLOPPY:
1493 return Bytecode::kStoreICSloppy; 1295 return Bytecode::kStoreICSloppy;
1494 case STRICT: 1296 case STRICT:
1495 return Bytecode::kStoreICStrict; 1297 return Bytecode::kStoreICStrict;
1496 default: 1298 default:
1497 UNREACHABLE(); 1299 UNREACHABLE();
1498 } 1300 }
1499 return static_cast<Bytecode>(-1); 1301 return Bytecode::kIllegal;
1500 } 1302 }
1501 1303
1502 1304
1503 // static 1305 // static
1504 Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC( 1306 Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC(
1505 LanguageMode language_mode) { 1307 LanguageMode language_mode) {
1506 switch (language_mode) { 1308 switch (language_mode) {
1507 case SLOPPY: 1309 case SLOPPY:
1508 return Bytecode::kKeyedStoreICSloppy; 1310 return Bytecode::kKeyedStoreICSloppy;
1509 case STRICT: 1311 case STRICT:
1510 return Bytecode::kKeyedStoreICStrict; 1312 return Bytecode::kKeyedStoreICStrict;
1511 default: 1313 default:
1512 UNREACHABLE(); 1314 UNREACHABLE();
1513 } 1315 }
1514 return static_cast<Bytecode>(-1); 1316 return Bytecode::kIllegal;
1515 } 1317 }
1516 1318
1517 1319
1518 // static 1320 // static
1519 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { 1321 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
1520 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof 1322 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
1521 : Bytecode::kLdaGlobal; 1323 : Bytecode::kLdaGlobal;
1522 } 1324 }
1523 1325
1524 1326
1525 // static 1327 // static
1526 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( 1328 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
1527 LanguageMode language_mode) { 1329 LanguageMode language_mode) {
1528 switch (language_mode) { 1330 switch (language_mode) {
1529 case SLOPPY: 1331 case SLOPPY:
1530 return Bytecode::kStaGlobalSloppy; 1332 return Bytecode::kStaGlobalSloppy;
1531 case STRICT: 1333 case STRICT:
1532 return Bytecode::kStaGlobalStrict; 1334 return Bytecode::kStaGlobalStrict;
1533 default: 1335 default:
1534 UNREACHABLE(); 1336 UNREACHABLE();
1535 } 1337 }
1536 return static_cast<Bytecode>(-1); 1338 return Bytecode::kIllegal;
1537 } 1339 }
1538 1340
1539 1341
1540 // static 1342 // static
1541 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( 1343 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot(
1542 LanguageMode language_mode) { 1344 LanguageMode language_mode) {
1543 switch (language_mode) { 1345 switch (language_mode) {
1544 case SLOPPY: 1346 case SLOPPY:
1545 return Bytecode::kStaLookupSlotSloppy; 1347 return Bytecode::kStaLookupSlotSloppy;
1546 case STRICT: 1348 case STRICT:
1547 return Bytecode::kStaLookupSlotStrict; 1349 return Bytecode::kStaLookupSlotStrict;
1548 default: 1350 default:
1549 UNREACHABLE(); 1351 UNREACHABLE();
1550 } 1352 }
1551 return static_cast<Bytecode>(-1); 1353 return Bytecode::kIllegal;
1552 } 1354 }
1553 1355
1554 // static 1356 // static
1555 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( 1357 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
1556 CreateArgumentsType type) { 1358 CreateArgumentsType type) {
1557 switch (type) { 1359 switch (type) {
1558 case CreateArgumentsType::kMappedArguments: 1360 case CreateArgumentsType::kMappedArguments:
1559 return Bytecode::kCreateMappedArguments; 1361 return Bytecode::kCreateMappedArguments;
1560 case CreateArgumentsType::kUnmappedArguments: 1362 case CreateArgumentsType::kUnmappedArguments:
1561 return Bytecode::kCreateUnmappedArguments; 1363 return Bytecode::kCreateUnmappedArguments;
1562 case CreateArgumentsType::kRestParameter: 1364 case CreateArgumentsType::kRestParameter:
1563 return Bytecode::kCreateRestParameter; 1365 return Bytecode::kCreateRestParameter;
1564 } 1366 }
1565 UNREACHABLE(); 1367 UNREACHABLE();
1566 return static_cast<Bytecode>(-1); 1368 return Bytecode::kIllegal;
1567 } 1369 }
1568 1370
1569 1371
1570 // static 1372 // static
1571 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { 1373 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
1572 switch (language_mode) { 1374 switch (language_mode) {
1573 case SLOPPY: 1375 case SLOPPY:
1574 return Bytecode::kDeletePropertySloppy; 1376 return Bytecode::kDeletePropertySloppy;
1575 case STRICT: 1377 case STRICT:
1576 return Bytecode::kDeletePropertyStrict; 1378 return Bytecode::kDeletePropertyStrict;
1577 default: 1379 default:
1578 UNREACHABLE(); 1380 UNREACHABLE();
1579 } 1381 }
1580 return static_cast<Bytecode>(-1); 1382 return Bytecode::kIllegal;
1581 } 1383 }
1582 1384
1583 // static 1385 // static
1584 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) { 1386 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
1585 switch (tail_call_mode) { 1387 switch (tail_call_mode) {
1586 case TailCallMode::kDisallow: 1388 case TailCallMode::kDisallow:
1587 return Bytecode::kCall; 1389 return Bytecode::kCall;
1588 case TailCallMode::kAllow: 1390 case TailCallMode::kAllow:
1589 return Bytecode::kTailCall; 1391 return Bytecode::kTailCall;
1590 default: 1392 default:
1591 UNREACHABLE(); 1393 UNREACHABLE();
1592 } 1394 }
1593 return static_cast<Bytecode>(-1); 1395 return Bytecode::kIllegal;
1594 } 1396 }
1595 1397
1596 // static 1398 // static
1597 bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) { 1399 OperandSize BytecodeArrayBuilder::SizeForRegisterOperand(Register value) {
1598 return kMinUInt8 <= value && value <= kMaxUInt8; 1400 if (value.is_byte_operand()) {
1599 } 1401 return OperandSize::kByte;
1600 1402 } else if (value.is_short_operand()) {
1601 1403 return OperandSize::kShort;
1602 // static 1404 } else {
1603 bool BytecodeArrayBuilder::FitsInIdx8Operand(size_t value) { 1405 return OperandSize::kQuad;
1604 return value <= static_cast<size_t>(kMaxUInt8); 1406 }
1605 }
1606
1607
1608 // static
1609 bool BytecodeArrayBuilder::FitsInImm8Operand(int value) {
1610 return kMinInt8 <= value && value <= kMaxInt8;
1611 }
1612
1613
1614 // static
1615 bool BytecodeArrayBuilder::FitsInIdx16Operand(int value) {
1616 return kMinUInt16 <= value && value <= kMaxUInt16;
1617 }
1618
1619
1620 // static
1621 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) {
1622 return value <= static_cast<size_t>(kMaxUInt16);
1623 }
1624
1625
1626 // static
1627 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) {
1628 return RegisterTranslator::FitsInReg8Operand(value);
1629 } 1407 }
1630 1408
1631 // static 1409 // static
1632 bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) { 1410 OperandSize BytecodeArrayBuilder::SizeForSignedOperand(int value) {
1633 return value.is_byte_operand(); 1411 if (kMinInt8 <= value && value <= kMaxInt8) {
1634 } 1412 return OperandSize::kByte;
1635 1413 } else if (kMinInt16 <= value && value <= kMaxInt16) {
1636 1414 return OperandSize::kShort;
1637 // static 1415 } else {
1638 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { 1416 return OperandSize::kQuad;
1639 return RegisterTranslator::FitsInReg16Operand(value); 1417 }
1640 } 1418 }
1641 1419
1642 // static 1420 // static
1643 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { 1421 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(int value) {
1644 return value.is_short_operand(); 1422 DCHECK_GE(value, 0);
1423 if (value <= kMaxUInt8) {
1424 return OperandSize::kByte;
1425 } else if (value <= kMaxUInt16) {
1426 return OperandSize::kShort;
1427 } else {
1428 return OperandSize::kQuad;
1429 }
1430 }
1431
1432 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(size_t value) {
1433 if (value <= static_cast<size_t>(kMaxUInt8)) {
1434 return OperandSize::kByte;
1435 } else if (value <= static_cast<size_t>(kMaxUInt16)) {
1436 return OperandSize::kShort;
1437 } else if (value <= kMaxUInt32) {
1438 return OperandSize::kQuad;
1439 } else {
1440 UNREACHABLE();
1441 return OperandSize::kQuad;
1442 }
1443 }
1444
1445 OperandScale BytecodeArrayBuilder::OperandSizesToScale(OperandSize size0,
1446 OperandSize size1,
1447 OperandSize size2,
1448 OperandSize size3) {
1449 OperandSize upper = std::max(size0, size1);
1450 OperandSize lower = std::max(size2, size3);
1451 OperandSize result = std::max(upper, lower);
1452 // Operand sizes have been scaled before calling this function.
1453 // Currently all scalable operands are byte sized at
1454 // OperandScale::kSingle.
1455 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) ==
1456 static_cast<int>(OperandScale::kSingle) &&
1457 static_cast<int>(OperandSize::kShort) ==
1458 static_cast<int>(OperandScale::kDouble) &&
1459 static_cast<int>(OperandSize::kQuad) ==
1460 static_cast<int>(OperandScale::kQuadruple));
1461 OperandScale operand_scale = static_cast<OperandScale>(result);
1462 DCHECK(operand_scale == OperandScale::kSingle ||
1463 operand_scale == OperandScale::kDouble ||
1464 operand_scale == OperandScale::kQuadruple);
1465 return operand_scale;
1466 }
1467
1468 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) {
1469 return static_cast<uint32_t>(reg.ToOperand());
1470 }
1471
1472 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) {
1473 return Register::FromOperand(static_cast<int32_t>(operand));
1474 }
1475
1476 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) {
1477 switch (size) {
1478 case OperandSize::kByte:
1479 return static_cast<uint8_t>(value & 0xff);
1480 case OperandSize::kShort:
1481 return static_cast<uint16_t>(value & 0xffff);
1482 case OperandSize::kQuad:
1483 return static_cast<uint32_t>(value);
1484 case OperandSize::kNone:
1485 UNREACHABLE();
1486 }
1487 return 0;
1488 }
1489
1490 uint32_t BytecodeArrayBuilder::UnsignedOperand(int value) {
1491 DCHECK_GE(value, 0);
1492 return static_cast<uint32_t>(value);
1493 }
1494
1495 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) {
1496 DCHECK_LE(value, kMaxUInt32);
1497 return static_cast<uint32_t>(value);
1645 } 1498 }
1646 1499
1647 } // namespace interpreter 1500 } // namespace interpreter
1648 } // namespace internal 1501 } // namespace internal
1649 } // namespace v8 1502 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698