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

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

Powered by Google App Engine
This is Rietveld 408576698