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

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

Issue 2351763002: [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: Fix Chromium Windows bots. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-writer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-array-builder.h" 5 #include "src/interpreter/bytecode-array-builder.h"
6 6
7 #include "src/globals.h" 7 #include "src/globals.h"
8 #include "src/interpreter/bytecode-array-writer.h" 8 #include "src/interpreter/bytecode-array-writer.h"
9 #include "src/interpreter/bytecode-dead-code-optimizer.h" 9 #include "src/interpreter/bytecode-dead-code-optimizer.h"
10 #include "src/interpreter/bytecode-label.h" 10 #include "src/interpreter/bytecode-label.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 return reg.is_parameter() || reg.index() < locals_count(); 73 return reg.is_parameter() || reg.index() < locals_count();
74 } 74 }
75 75
76 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) { 76 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
77 DCHECK(return_seen_in_block_); 77 DCHECK(return_seen_in_block_);
78 DCHECK(!bytecode_generated_); 78 DCHECK(!bytecode_generated_);
79 bytecode_generated_ = true; 79 bytecode_generated_ = true;
80 80
81 Handle<FixedArray> handler_table = 81 Handle<FixedArray> handler_table =
82 handler_table_builder()->ToHandlerTable(isolate); 82 handler_table_builder()->ToHandlerTable(isolate);
83 return pipeline_->ToBytecodeArray(isolate, fixed_register_count(), 83 return pipeline_->ToBytecodeArray(isolate,
84 fixed_and_temporary_register_count(),
84 parameter_count(), handler_table); 85 parameter_count(), handler_table);
85 } 86 }
86 87
87 namespace {
88
89 static bool ExpressionPositionIsNeeded(Bytecode bytecode) {
90 // An expression position is always needed if filtering is turned
91 // off. Otherwise an expression is only needed if the bytecode has
92 // external side effects.
93 return !FLAG_ignition_filter_expression_positions ||
94 !Bytecodes::IsWithoutExternalSideEffects(bytecode);
95 }
96
97 } // namespace
98
99 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) {
100 if (latest_source_info_.is_valid()) {
101 // Statement positions need to be emitted immediately. Expression
102 // positions can be pushed back until a bytecode is found that can
103 // throw. Hence we only invalidate the existing source position
104 // information if it is used.
105 if (latest_source_info_.is_statement() ||
106 ExpressionPositionIsNeeded(node->bytecode())) {
107 node->source_info().Clone(latest_source_info_);
108 latest_source_info_.set_invalid();
109 }
110 }
111 }
112
113 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 88 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
114 uint32_t operand1, uint32_t operand2, 89 uint32_t operand1, uint32_t operand2,
115 uint32_t operand3) { 90 uint32_t operand3) {
116 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); 91 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3));
117 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); 92 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3,
118 AttachSourceInfo(&node); 93 &latest_source_info_);
119 pipeline()->Write(&node); 94 pipeline()->Write(&node);
120 } 95 }
121 96
122 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 97 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
123 uint32_t operand1, uint32_t operand2) { 98 uint32_t operand1, uint32_t operand2) {
124 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); 99 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2));
125 BytecodeNode node(bytecode, operand0, operand1, operand2); 100 BytecodeNode node(bytecode, operand0, operand1, operand2,
126 AttachSourceInfo(&node); 101 &latest_source_info_);
127 pipeline()->Write(&node); 102 pipeline()->Write(&node);
128 } 103 }
129 104
130 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 105 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
131 uint32_t operand1) { 106 uint32_t operand1) {
132 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); 107 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1));
133 BytecodeNode node(bytecode, operand0, operand1); 108 BytecodeNode node(bytecode, operand0, operand1, &latest_source_info_);
134 AttachSourceInfo(&node);
135 pipeline()->Write(&node); 109 pipeline()->Write(&node);
136 } 110 }
137 111
138 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { 112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) {
139 DCHECK(OperandsAreValid(bytecode, 1, operand0)); 113 DCHECK(OperandsAreValid(bytecode, 1, operand0));
140 BytecodeNode node(bytecode, operand0); 114 BytecodeNode node(bytecode, operand0, &latest_source_info_);
141 AttachSourceInfo(&node);
142 pipeline()->Write(&node); 115 pipeline()->Write(&node);
143 } 116 }
144 117
145 void BytecodeArrayBuilder::Output(Bytecode bytecode) { 118 void BytecodeArrayBuilder::Output(Bytecode bytecode) {
146 DCHECK(OperandsAreValid(bytecode, 0)); 119 DCHECK(OperandsAreValid(bytecode, 0));
147 BytecodeNode node(bytecode); 120 BytecodeNode node(bytecode, &latest_source_info_);
148 AttachSourceInfo(&node);
149 pipeline()->Write(&node); 121 pipeline()->Write(&node);
150 } 122 }
151 123
124 void BytecodeArrayBuilder::OutputJump(Bytecode bytecode, BytecodeLabel* label) {
125 BytecodeNode node(bytecode, 0, &latest_source_info_);
126 pipeline_->WriteJump(&node, label);
127 LeaveBasicBlock();
128 }
129
130 void BytecodeArrayBuilder::OutputJump(Bytecode bytecode, uint32_t operand0,
131 BytecodeLabel* label) {
132 BytecodeNode node(bytecode, 0, operand0, &latest_source_info_);
133 pipeline_->WriteJump(&node, label);
134 LeaveBasicBlock();
135 }
136
152 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 137 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
153 Register reg, 138 Register reg,
154 int feedback_slot) { 139 int feedback_slot) {
155 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg), 140 switch (op) {
156 UnsignedOperand(feedback_slot)); 141 case Token::Value::ADD:
142 Output(Bytecode::kAdd, RegisterOperand(reg),
143 UnsignedOperand(feedback_slot));
144 break;
145 case Token::Value::SUB:
146 Output(Bytecode::kSub, RegisterOperand(reg),
147 UnsignedOperand(feedback_slot));
148 break;
149 case Token::Value::MUL:
150 Output(Bytecode::kMul, RegisterOperand(reg),
151 UnsignedOperand(feedback_slot));
152 break;
153 case Token::Value::DIV:
154 Output(Bytecode::kDiv, RegisterOperand(reg),
155 UnsignedOperand(feedback_slot));
156 break;
157 case Token::Value::MOD:
158 Output(Bytecode::kMod, RegisterOperand(reg),
159 UnsignedOperand(feedback_slot));
160 break;
161 case Token::Value::BIT_OR:
162 Output(Bytecode::kBitwiseOr, RegisterOperand(reg),
163 UnsignedOperand(feedback_slot));
164 break;
165 case Token::Value::BIT_XOR:
166 Output(Bytecode::kBitwiseXor, RegisterOperand(reg),
167 UnsignedOperand(feedback_slot));
168 break;
169 case Token::Value::BIT_AND:
170 Output(Bytecode::kBitwiseAnd, RegisterOperand(reg),
171 UnsignedOperand(feedback_slot));
172 break;
173 case Token::Value::SHL:
174 Output(Bytecode::kShiftLeft, RegisterOperand(reg),
175 UnsignedOperand(feedback_slot));
176 break;
177 case Token::Value::SAR:
178 Output(Bytecode::kShiftRight, RegisterOperand(reg),
179 UnsignedOperand(feedback_slot));
180 break;
181 case Token::Value::SHR:
182 Output(Bytecode::kShiftRightLogical, RegisterOperand(reg),
183 UnsignedOperand(feedback_slot));
184 break;
185 default:
186 UNREACHABLE();
187 }
157 return *this; 188 return *this;
158 } 189 }
159 190
160 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, 191 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
161 int feedback_slot) { 192 int feedback_slot) {
162 Output(BytecodeForCountOperation(op), UnsignedOperand(feedback_slot)); 193 if (op == Token::Value::ADD) {
194 Output(Bytecode::kInc, UnsignedOperand(feedback_slot));
195 } else {
196 DCHECK_EQ(op, Token::Value::SUB);
197 Output(Bytecode::kDec, UnsignedOperand(feedback_slot));
198 }
163 return *this; 199 return *this;
164 } 200 }
165 201
166 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { 202 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() {
167 Output(Bytecode::kToBooleanLogicalNot); 203 Output(Bytecode::kToBooleanLogicalNot);
168 return *this; 204 return *this;
169 } 205 }
170 206
171
172 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { 207 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
173 Output(Bytecode::kTypeOf); 208 Output(Bytecode::kTypeOf);
174 return *this; 209 return *this;
175 } 210 }
176 211
177 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( 212 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
178 Token::Value op, Register reg, int feedback_slot) { 213 Token::Value op, Register reg, int feedback_slot) {
179 if (op == Token::INSTANCEOF || op == Token::IN) { 214 switch (op) {
180 Output(BytecodeForCompareOperation(op), RegisterOperand(reg)); 215 case Token::Value::EQ:
181 } else { 216 Output(Bytecode::kTestEqual, RegisterOperand(reg),
182 Output(BytecodeForCompareOperation(op), RegisterOperand(reg), 217 UnsignedOperand(feedback_slot));
183 UnsignedOperand(feedback_slot)); 218 break;
219 case Token::Value::NE:
220 Output(Bytecode::kTestNotEqual, RegisterOperand(reg),
221 UnsignedOperand(feedback_slot));
222 break;
223 case Token::Value::EQ_STRICT:
224 Output(Bytecode::kTestEqualStrict, RegisterOperand(reg),
225 UnsignedOperand(feedback_slot));
226 break;
227 case Token::Value::LT:
228 Output(Bytecode::kTestLessThan, RegisterOperand(reg),
229 UnsignedOperand(feedback_slot));
230 break;
231 case Token::Value::GT:
232 Output(Bytecode::kTestGreaterThan, RegisterOperand(reg),
233 UnsignedOperand(feedback_slot));
234 break;
235 case Token::Value::LTE:
236 Output(Bytecode::kTestLessThanOrEqual, RegisterOperand(reg),
237 UnsignedOperand(feedback_slot));
238 break;
239 case Token::Value::GTE:
240 Output(Bytecode::kTestGreaterThanOrEqual, RegisterOperand(reg),
241 UnsignedOperand(feedback_slot));
242 break;
243 case Token::Value::INSTANCEOF:
244 Output(Bytecode::kTestInstanceOf, RegisterOperand(reg));
245 break;
246 case Token::Value::IN:
247 Output(Bytecode::kTestIn, RegisterOperand(reg));
248 break;
249 default:
250 UNREACHABLE();
184 } 251 }
185 return *this; 252 return *this;
186 } 253 }
187 254
188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( 255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry(
189 size_t entry) { 256 size_t entry) {
190 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); 257 Output(Bytecode::kLdaConstant, UnsignedOperand(entry));
191 return *this; 258 return *this;
192 } 259 }
193 260
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 314
248 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, 315 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
249 Register to) { 316 Register to) {
250 DCHECK(from != to); 317 DCHECK(from != to);
251 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); 318 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to));
252 return *this; 319 return *this;
253 } 320 }
254 321
255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, 322 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot,
256 TypeofMode typeof_mode) { 323 TypeofMode typeof_mode) {
257 // TODO(rmcilroy): Potentially store typeof information in an 324 if (typeof_mode == INSIDE_TYPEOF) {
258 // operand rather than having extra bytecodes. 325 Output(Bytecode::kLdaGlobalInsideTypeof, feedback_slot);
259 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); 326 } else {
260 Output(bytecode, UnsignedOperand(feedback_slot)); 327 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF);
328 Output(Bytecode::kLdaGlobal, UnsignedOperand(feedback_slot));
329 }
261 return *this; 330 return *this;
262 } 331 }
263 332
264 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( 333 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
265 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { 334 const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
266 Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
267 size_t name_index = GetConstantPoolEntry(name); 335 size_t name_index = GetConstantPoolEntry(name);
268 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); 336 if (language_mode == SLOPPY) {
337 Output(Bytecode::kStaGlobalSloppy, UnsignedOperand(name_index),
338 UnsignedOperand(feedback_slot));
339 } else {
340 DCHECK_EQ(language_mode, STRICT);
341 Output(Bytecode::kStaGlobalStrict, UnsignedOperand(name_index),
342 UnsignedOperand(feedback_slot));
343 }
269 return *this; 344 return *this;
270 } 345 }
271 346
272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, 347 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
273 int slot_index, 348 int slot_index,
274 int depth) { 349 int depth) {
275 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), 350 Output(Bytecode::kLdaContextSlot, RegisterOperand(context),
276 UnsignedOperand(slot_index), UnsignedOperand(depth)); 351 UnsignedOperand(slot_index), UnsignedOperand(depth));
277 return *this; 352 return *this;
278 } 353 }
279 354
280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, 355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
281 int slot_index, 356 int slot_index,
282 int depth) { 357 int depth) {
283 Output(Bytecode::kStaContextSlot, RegisterOperand(context), 358 Output(Bytecode::kStaContextSlot, RegisterOperand(context),
284 UnsignedOperand(slot_index), UnsignedOperand(depth)); 359 UnsignedOperand(slot_index), UnsignedOperand(depth));
285 return *this; 360 return *this;
286 } 361 }
287 362
288 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( 363 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
289 const Handle<String> name, TypeofMode typeof_mode) { 364 const Handle<String> name, TypeofMode typeof_mode) {
290 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
291 ? Bytecode::kLdaLookupSlotInsideTypeof
292 : Bytecode::kLdaLookupSlot;
293 size_t name_index = GetConstantPoolEntry(name); 365 size_t name_index = GetConstantPoolEntry(name);
294 Output(bytecode, UnsignedOperand(name_index)); 366 if (typeof_mode == INSIDE_TYPEOF) {
367 Output(Bytecode::kLdaLookupSlotInsideTypeof, UnsignedOperand(name_index));
368 } else {
369 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF);
370 Output(Bytecode::kLdaLookupSlot, UnsignedOperand(name_index));
371 }
295 return *this; 372 return *this;
296 } 373 }
297 374
298 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( 375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot(
299 const Handle<String> name, TypeofMode typeof_mode, int slot_index, 376 const Handle<String> name, TypeofMode typeof_mode, int slot_index,
300 int depth) { 377 int depth) {
301 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) 378 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
302 ? Bytecode::kLdaLookupContextSlotInsideTypeof 379 ? Bytecode::kLdaLookupContextSlotInsideTypeof
303 : Bytecode::kLdaLookupContextSlot; 380 : Bytecode::kLdaLookupContextSlot;
304 size_t name_index = GetConstantPoolEntry(name); 381 size_t name_index = GetConstantPoolEntry(name);
305 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), 382 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index),
306 UnsignedOperand(depth)); 383 UnsignedOperand(depth));
307 return *this; 384 return *this;
308 } 385 }
309 386
310 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( 387 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot(
311 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, 388 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot,
312 int depth) { 389 int depth) {
313 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) 390 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
314 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof 391 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof
315 : Bytecode::kLdaLookupGlobalSlot; 392 : Bytecode::kLdaLookupGlobalSlot;
316 size_t name_index = GetConstantPoolEntry(name); 393 size_t name_index = GetConstantPoolEntry(name);
317 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), 394 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot),
318 UnsignedOperand(depth)); 395 UnsignedOperand(depth));
319 return *this; 396 return *this;
320 } 397 }
321 398
322 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( 399 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
323 const Handle<String> name, LanguageMode language_mode) { 400 const Handle<String> name, LanguageMode language_mode) {
324 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
325 size_t name_index = GetConstantPoolEntry(name); 401 size_t name_index = GetConstantPoolEntry(name);
326 Output(bytecode, UnsignedOperand(name_index)); 402 if (language_mode == SLOPPY) {
403 Output(Bytecode::kStaLookupSlotSloppy, UnsignedOperand(name_index));
404 } else {
405 DCHECK_EQ(language_mode, STRICT);
406 Output(Bytecode::kStaLookupSlotStrict, UnsignedOperand(name_index));
407 }
327 return *this; 408 return *this;
328 } 409 }
329 410
330 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( 411 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
331 Register object, const Handle<Name> name, int feedback_slot) { 412 Register object, const Handle<Name> name, int feedback_slot) {
332 size_t name_index = GetConstantPoolEntry(name); 413 size_t name_index = GetConstantPoolEntry(name);
333 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), 414 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object),
334 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); 415 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
335 return *this; 416 return *this;
336 } 417 }
337 418
338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( 419 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
339 Register object, int feedback_slot) { 420 Register object, int feedback_slot) {
340 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), 421 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object),
341 UnsignedOperand(feedback_slot)); 422 UnsignedOperand(feedback_slot));
342 return *this; 423 return *this;
343 } 424 }
344 425
345 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( 426 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
346 Register object, const Handle<Name> name, int feedback_slot, 427 Register object, const Handle<Name> name, int feedback_slot,
347 LanguageMode language_mode) { 428 LanguageMode language_mode) {
348 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode);
349 size_t name_index = GetConstantPoolEntry(name); 429 size_t name_index = GetConstantPoolEntry(name);
350 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index), 430 if (language_mode == SLOPPY) {
351 UnsignedOperand(feedback_slot)); 431 Output(Bytecode::kStaNamedPropertySloppy, RegisterOperand(object),
432 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
433 } else {
434 DCHECK_EQ(language_mode, STRICT);
435 Output(Bytecode::kStaNamedPropertyStrict, RegisterOperand(object),
436 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
437 }
352 return *this; 438 return *this;
353 } 439 }
354 440
355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( 441 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
356 Register object, Register key, int feedback_slot, 442 Register object, Register key, int feedback_slot,
357 LanguageMode language_mode) { 443 LanguageMode language_mode) {
358 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); 444 if (language_mode == SLOPPY) {
359 Output(bytecode, RegisterOperand(object), RegisterOperand(key), 445 Output(Bytecode::kStaKeyedPropertySloppy, RegisterOperand(object),
360 UnsignedOperand(feedback_slot)); 446 RegisterOperand(key), UnsignedOperand(feedback_slot));
447 } else {
448 DCHECK_EQ(language_mode, STRICT);
449 Output(Bytecode::kStaKeyedPropertyStrict, RegisterOperand(object),
450 RegisterOperand(key), UnsignedOperand(feedback_slot));
451 }
361 return *this; 452 return *this;
362 } 453 }
363 454
364 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, 455 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry,
365 int flags) { 456 int flags) {
366 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), 457 Output(Bytecode::kCreateClosure, UnsignedOperand(entry),
367 UnsignedOperand(flags)); 458 UnsignedOperand(flags));
368 return *this; 459 return *this;
369 } 460 }
370 461
(...skipping 21 matching lines...) Expand all
392 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( 483 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(
393 Register object, Handle<ScopeInfo> scope_info) { 484 Register object, Handle<ScopeInfo> scope_info) {
394 size_t scope_info_index = GetConstantPoolEntry(scope_info); 485 size_t scope_info_index = GetConstantPoolEntry(scope_info);
395 Output(Bytecode::kCreateWithContext, RegisterOperand(object), 486 Output(Bytecode::kCreateWithContext, RegisterOperand(object),
396 UnsignedOperand(scope_info_index)); 487 UnsignedOperand(scope_info_index));
397 return *this; 488 return *this;
398 } 489 }
399 490
400 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( 491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
401 CreateArgumentsType type) { 492 CreateArgumentsType type) {
402 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather 493 switch (type) {
403 // than having two different bytecodes once we have better support for 494 case CreateArgumentsType::kMappedArguments:
404 // branches in the InterpreterAssembler. 495 Output(Bytecode::kCreateMappedArguments);
405 Bytecode bytecode = BytecodeForCreateArguments(type); 496 break;
406 Output(bytecode); 497 case CreateArgumentsType::kUnmappedArguments:
498 Output(Bytecode::kCreateUnmappedArguments);
499 break;
500 case CreateArgumentsType::kRestParameter:
501 Output(Bytecode::kCreateRestParameter);
502 break;
503 default:
504 UNREACHABLE();
505 }
407 return *this; 506 return *this;
408 } 507 }
409 508
410 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( 509 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
411 Handle<String> pattern, int literal_index, int flags) { 510 Handle<String> pattern, int literal_index, int flags) {
412 size_t pattern_entry = GetConstantPoolEntry(pattern); 511 size_t pattern_entry = GetConstantPoolEntry(pattern);
413 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), 512 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry),
414 UnsignedOperand(literal_index), UnsignedOperand(flags)); 513 UnsignedOperand(literal_index), UnsignedOperand(flags));
415 return *this; 514 return *this;
416 } 515 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 return *this; 568 return *this;
470 } 569 }
471 570
472 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, 571 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
473 BytecodeLabel* label) { 572 BytecodeLabel* label) {
474 pipeline_->BindLabel(target, label); 573 pipeline_->BindLabel(target, label);
475 LeaveBasicBlock(); 574 LeaveBasicBlock();
476 return *this; 575 return *this;
477 } 576 }
478 577
479 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node,
480 BytecodeLabel* label) {
481 AttachSourceInfo(node);
482 pipeline_->WriteJump(node, label);
483 LeaveBasicBlock();
484 return *this;
485 }
486
487 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { 578 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
488 BytecodeNode node(Bytecode::kJump, 0); 579 OutputJump(Bytecode::kJump, label);
489 return OutputJump(&node, label); 580 return *this;
490 } 581 }
491 582
492 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { 583 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
493 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue 584 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue
494 // to JumpIfTrue. 585 // to JumpIfTrue.
495 BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0); 586 OutputJump(Bytecode::kJumpIfToBooleanTrue, label);
496 return OutputJump(&node, label); 587 return *this;
497 } 588 }
498 589
499 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { 590 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
500 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse 591 OutputJump(Bytecode::kJumpIfToBooleanFalse, label);
501 // to JumpIfFalse. 592 return *this;
502 BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0);
503 return OutputJump(&node, label);
504 } 593 }
505 594
506 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { 595 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
507 BytecodeNode node(Bytecode::kJumpIfNull, 0); 596 OutputJump(Bytecode::kJumpIfNull, label);
508 return OutputJump(&node, label); 597 return *this;
509 } 598 }
510 599
511 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( 600 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
512 BytecodeLabel* label) { 601 BytecodeLabel* label) {
513 BytecodeNode node(Bytecode::kJumpIfUndefined, 0); 602 OutputJump(Bytecode::kJumpIfUndefined, label);
514 return OutputJump(&node, label); 603 return *this;
515 } 604 }
516 605
517 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( 606 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
518 BytecodeLabel* label) { 607 BytecodeLabel* label) {
519 BytecodeNode node(Bytecode::kJumpIfNotHole, 0); 608 OutputJump(Bytecode::kJumpIfNotHole, label);
520 return OutputJump(&node, label); 609 return *this;
521 } 610 }
522 611
523 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, 612 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
524 int loop_depth) { 613 int loop_depth) {
525 BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth)); 614 OutputJump(Bytecode::kJumpLoop, UnsignedOperand(loop_depth), label);
526 return OutputJump(&node, label); 615 return *this;
527 } 616 }
528 617
529 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { 618 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
530 if (position != kNoSourcePosition) { 619 if (position != kNoSourcePosition) {
531 // We need to attach a non-breakable source position to a stack 620 // We need to attach a non-breakable source position to a stack
532 // check, so we simply add it as expression position. There can be 621 // check, so we simply add it as expression position. There can be
533 // a prior statement position from constructs like: 622 // a prior statement position from constructs like:
534 // 623 //
535 // do var x; while (false); 624 // do var x; while (false);
536 // 625 //
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 Return(); 726 Return();
638 } 727 }
639 DCHECK(return_seen_in_block_); 728 DCHECK(return_seen_in_block_);
640 } 729 }
641 730
642 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 731 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
643 Register receiver_args, 732 Register receiver_args,
644 size_t receiver_args_count, 733 size_t receiver_args_count,
645 int feedback_slot, 734 int feedback_slot,
646 TailCallMode tail_call_mode) { 735 TailCallMode tail_call_mode) {
647 Bytecode bytecode = BytecodeForCall(tail_call_mode); 736 if (tail_call_mode == TailCallMode::kDisallow) {
648 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args), 737 Output(Bytecode::kCall, RegisterOperand(callable),
649 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot)); 738 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count),
739 UnsignedOperand(feedback_slot));
740 } else {
741 DCHECK(tail_call_mode == TailCallMode::kAllow);
742 Output(Bytecode::kTailCall, RegisterOperand(callable),
743 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count),
744 UnsignedOperand(feedback_slot));
745 }
650 return *this; 746 return *this;
651 } 747 }
652 748
653 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, 749 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
654 Register first_arg, 750 Register first_arg,
655 size_t arg_count, 751 size_t arg_count,
656 int feedback_slot_id) { 752 int feedback_slot_id) {
657 if (!first_arg.is_valid()) { 753 if (!first_arg.is_valid()) {
658 DCHECK_EQ(0u, arg_count); 754 DCHECK_EQ(0u, arg_count);
659 first_arg = Register(0); 755 first_arg = Register(0);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 798
703 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( 799 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
704 int context_index, Register receiver_args, size_t receiver_args_count) { 800 int context_index, Register receiver_args, size_t receiver_args_count) {
705 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), 801 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index),
706 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); 802 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count));
707 return *this; 803 return *this;
708 } 804 }
709 805
710 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 806 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
711 LanguageMode language_mode) { 807 LanguageMode language_mode) {
712 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); 808 if (language_mode == SLOPPY) {
809 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object));
810 } else {
811 DCHECK_EQ(language_mode, STRICT);
812 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object));
813 }
713 return *this; 814 return *this;
714 } 815 }
715 816
716 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 817 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
717 return constant_array_builder()->Insert(object); 818 return constant_array_builder()->Insert(object);
718 } 819 }
719 820
720 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { 821 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() {
721 return constant_array_builder()->AllocateEntry(); 822 return constant_array_builder()->AllocateEntry();
722 } 823 }
723 824
724 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, 825 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry,
725 Handle<Object> object) { 826 Handle<Object> object) {
726 constant_array_builder()->InsertAllocatedEntry(entry, object); 827 constant_array_builder()->InsertAllocatedEntry(entry, object);
727 } 828 }
728 829
729 void BytecodeArrayBuilder::SetReturnPosition() { 830 void BytecodeArrayBuilder::SetReturnPosition() {
730 if (return_position_ == kNoSourcePosition) return; 831 if (return_position_ == kNoSourcePosition) return;
731 latest_source_info_.MakeStatementPosition(return_position_); 832 latest_source_info_.MakeStatementPosition(return_position_);
732 } 833 }
733 834
734 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
735 if (stmt->position() == kNoSourcePosition) return;
736 latest_source_info_.MakeStatementPosition(stmt->position());
737 }
738
739 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
740 if (expr->position() == kNoSourcePosition) return;
741 if (!latest_source_info_.is_statement()) {
742 // Ensure the current expression position is overwritten with the
743 // latest value.
744 latest_source_info_.MakeExpressionPosition(expr->position());
745 }
746 }
747
748 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) {
749 if (expr->position() == kNoSourcePosition) return;
750 latest_source_info_.MakeStatementPosition(expr->position());
751 }
752
753 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { 835 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
754 return temporary_register_allocator()->RegisterIsLive(reg); 836 return temporary_register_allocator()->RegisterIsLive(reg);
755 } 837 }
756 838
757 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { 839 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
758 if (!reg.is_valid()) { 840 if (!reg.is_valid()) {
759 return false; 841 return false;
760 } 842 }
761 843
762 if (reg.is_current_context() || reg.is_function_closure() || 844 if (reg.is_current_context() || reg.is_function_closure() ||
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 888 }
807 break; 889 break;
808 case OperandType::kRuntimeId: 890 case OperandType::kRuntimeId:
809 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > 891 if (Bytecodes::SizeForUnsignedOperand(operands[i]) >
810 OperandSize::kShort) { 892 OperandSize::kShort) {
811 return false; 893 return false;
812 } 894 }
813 break; 895 break;
814 case OperandType::kIdx: 896 case OperandType::kIdx:
815 // TODO(leszeks): Possibly split this up into constant pool indices and 897 // TODO(leszeks): Possibly split this up into constant pool indices and
816 // other indices, for checking 898 // other indices, for checking.
817 break; 899 break;
818 case OperandType::kUImm: 900 case OperandType::kUImm:
819 case OperandType::kImm: 901 case OperandType::kImm:
820 break; 902 break;
821 case OperandType::kMaybeReg: 903 case OperandType::kMaybeReg:
822 if (Register::FromOperand(operands[i]) == Register(0)) { 904 if (Register::FromOperand(operands[i]) == Register(0)) {
823 break; 905 break;
824 } 906 }
825 // Fall-through to kReg case. 907 // Fall-through to kReg case.
826 case OperandType::kReg: 908 case OperandType::kReg:
(...skipping 22 matching lines...) Expand all
849 return false; 931 return false;
850 } 932 }
851 break; 933 break;
852 } 934 }
853 } 935 }
854 } 936 }
855 937
856 return true; 938 return true;
857 } 939 }
858 940
859 // static
860 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
861 switch (op) {
862 case Token::Value::ADD:
863 return Bytecode::kAdd;
864 case Token::Value::SUB:
865 return Bytecode::kSub;
866 case Token::Value::MUL:
867 return Bytecode::kMul;
868 case Token::Value::DIV:
869 return Bytecode::kDiv;
870 case Token::Value::MOD:
871 return Bytecode::kMod;
872 case Token::Value::BIT_OR:
873 return Bytecode::kBitwiseOr;
874 case Token::Value::BIT_XOR:
875 return Bytecode::kBitwiseXor;
876 case Token::Value::BIT_AND:
877 return Bytecode::kBitwiseAnd;
878 case Token::Value::SHL:
879 return Bytecode::kShiftLeft;
880 case Token::Value::SAR:
881 return Bytecode::kShiftRight;
882 case Token::Value::SHR:
883 return Bytecode::kShiftRightLogical;
884 default:
885 UNREACHABLE();
886 return Bytecode::kIllegal;
887 }
888 }
889
890 // static
891 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) {
892 switch (op) {
893 case Token::Value::ADD:
894 return Bytecode::kInc;
895 case Token::Value::SUB:
896 return Bytecode::kDec;
897 default:
898 UNREACHABLE();
899 return Bytecode::kIllegal;
900 }
901 }
902
903 // static
904 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
905 switch (op) {
906 case Token::Value::EQ:
907 return Bytecode::kTestEqual;
908 case Token::Value::NE:
909 return Bytecode::kTestNotEqual;
910 case Token::Value::EQ_STRICT:
911 return Bytecode::kTestEqualStrict;
912 case Token::Value::LT:
913 return Bytecode::kTestLessThan;
914 case Token::Value::GT:
915 return Bytecode::kTestGreaterThan;
916 case Token::Value::LTE:
917 return Bytecode::kTestLessThanOrEqual;
918 case Token::Value::GTE:
919 return Bytecode::kTestGreaterThanOrEqual;
920 case Token::Value::INSTANCEOF:
921 return Bytecode::kTestInstanceOf;
922 case Token::Value::IN:
923 return Bytecode::kTestIn;
924 default:
925 UNREACHABLE();
926 return Bytecode::kIllegal;
927 }
928 }
929
930 // static
931 Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty(
932 LanguageMode language_mode) {
933 switch (language_mode) {
934 case SLOPPY:
935 return Bytecode::kStaNamedPropertySloppy;
936 case STRICT:
937 return Bytecode::kStaNamedPropertyStrict;
938 default:
939 UNREACHABLE();
940 }
941 return Bytecode::kIllegal;
942 }
943
944 // static
945 Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty(
946 LanguageMode language_mode) {
947 switch (language_mode) {
948 case SLOPPY:
949 return Bytecode::kStaKeyedPropertySloppy;
950 case STRICT:
951 return Bytecode::kStaKeyedPropertyStrict;
952 default:
953 UNREACHABLE();
954 }
955 return Bytecode::kIllegal;
956 }
957
958 // static
959 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
960 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
961 : Bytecode::kLdaGlobal;
962 }
963
964 // static
965 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
966 LanguageMode language_mode) {
967 switch (language_mode) {
968 case SLOPPY:
969 return Bytecode::kStaGlobalSloppy;
970 case STRICT:
971 return Bytecode::kStaGlobalStrict;
972 default:
973 UNREACHABLE();
974 }
975 return Bytecode::kIllegal;
976 }
977
978 // static
979 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot(
980 LanguageMode language_mode) {
981 switch (language_mode) {
982 case SLOPPY:
983 return Bytecode::kStaLookupSlotSloppy;
984 case STRICT:
985 return Bytecode::kStaLookupSlotStrict;
986 default:
987 UNREACHABLE();
988 }
989 return Bytecode::kIllegal;
990 }
991
992 // static
993 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
994 CreateArgumentsType type) {
995 switch (type) {
996 case CreateArgumentsType::kMappedArguments:
997 return Bytecode::kCreateMappedArguments;
998 case CreateArgumentsType::kUnmappedArguments:
999 return Bytecode::kCreateUnmappedArguments;
1000 case CreateArgumentsType::kRestParameter:
1001 return Bytecode::kCreateRestParameter;
1002 }
1003 UNREACHABLE();
1004 return Bytecode::kIllegal;
1005 }
1006
1007 // static
1008 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
1009 switch (language_mode) {
1010 case SLOPPY:
1011 return Bytecode::kDeletePropertySloppy;
1012 case STRICT:
1013 return Bytecode::kDeletePropertyStrict;
1014 default:
1015 UNREACHABLE();
1016 }
1017 return Bytecode::kIllegal;
1018 }
1019
1020 // static
1021 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
1022 switch (tail_call_mode) {
1023 case TailCallMode::kDisallow:
1024 return Bytecode::kCall;
1025 case TailCallMode::kAllow:
1026 return Bytecode::kTailCall;
1027 default:
1028 UNREACHABLE();
1029 }
1030 return Bytecode::kIllegal;
1031 }
1032
1033 } // namespace interpreter 941 } // namespace interpreter
1034 } // namespace internal 942 } // namespace internal
1035 } // namespace v8 943 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698