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

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

Powered by Google App Engine
This is Rietveld 408576698