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

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

Powered by Google App Engine
This is Rietveld 408576698