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

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

Issue 2358423002: Version 5.5.251.1 (cherry-pick) (Closed)
Patch Set: 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, 83 return pipeline_->ToBytecodeArray(isolate, fixed_register_count(),
84 fixed_and_temporary_register_count(),
85 parameter_count(), handler_table); 84 parameter_count(), handler_table);
86 } 85 }
87 86
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
88 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 113 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
89 uint32_t operand1, uint32_t operand2, 114 uint32_t operand1, uint32_t operand2,
90 uint32_t operand3) { 115 uint32_t operand3) {
91 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); 116 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3));
92 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, 117 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3);
93 &latest_source_info_); 118 AttachSourceInfo(&node);
94 pipeline()->Write(&node); 119 pipeline()->Write(&node);
95 } 120 }
96 121
97 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 122 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
98 uint32_t operand1, uint32_t operand2) { 123 uint32_t operand1, uint32_t operand2) {
99 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); 124 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2));
100 BytecodeNode node(bytecode, operand0, operand1, operand2, 125 BytecodeNode node(bytecode, operand0, operand1, operand2);
101 &latest_source_info_); 126 AttachSourceInfo(&node);
102 pipeline()->Write(&node); 127 pipeline()->Write(&node);
103 } 128 }
104 129
105 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 130 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
106 uint32_t operand1) { 131 uint32_t operand1) {
107 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); 132 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1));
108 BytecodeNode node(bytecode, operand0, operand1, &latest_source_info_); 133 BytecodeNode node(bytecode, operand0, operand1);
134 AttachSourceInfo(&node);
109 pipeline()->Write(&node); 135 pipeline()->Write(&node);
110 } 136 }
111 137
112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { 138 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) {
113 DCHECK(OperandsAreValid(bytecode, 1, operand0)); 139 DCHECK(OperandsAreValid(bytecode, 1, operand0));
114 BytecodeNode node(bytecode, operand0, &latest_source_info_); 140 BytecodeNode node(bytecode, operand0);
141 AttachSourceInfo(&node);
115 pipeline()->Write(&node); 142 pipeline()->Write(&node);
116 } 143 }
117 144
118 void BytecodeArrayBuilder::Output(Bytecode bytecode) { 145 void BytecodeArrayBuilder::Output(Bytecode bytecode) {
119 DCHECK(OperandsAreValid(bytecode, 0)); 146 DCHECK(OperandsAreValid(bytecode, 0));
120 BytecodeNode node(bytecode, &latest_source_info_); 147 BytecodeNode node(bytecode);
148 AttachSourceInfo(&node);
121 pipeline()->Write(&node); 149 pipeline()->Write(&node);
122 } 150 }
123 151
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
137 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 152 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
138 Register reg, 153 Register reg,
139 int feedback_slot) { 154 int feedback_slot) {
140 switch (op) { 155 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg),
141 case Token::Value::ADD: 156 UnsignedOperand(feedback_slot));
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 }
188 return *this; 157 return *this;
189 } 158 }
190 159
191 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, 160 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
192 int feedback_slot) { 161 int feedback_slot) {
193 if (op == Token::Value::ADD) { 162 Output(BytecodeForCountOperation(op), UnsignedOperand(feedback_slot));
194 Output(Bytecode::kInc, UnsignedOperand(feedback_slot));
195 } else {
196 DCHECK_EQ(op, Token::Value::SUB);
197 Output(Bytecode::kDec, UnsignedOperand(feedback_slot));
198 }
199 return *this; 163 return *this;
200 } 164 }
201 165
202 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { 166 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() {
203 Output(Bytecode::kToBooleanLogicalNot); 167 Output(Bytecode::kToBooleanLogicalNot);
204 return *this; 168 return *this;
205 } 169 }
206 170
171
207 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { 172 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
208 Output(Bytecode::kTypeOf); 173 Output(Bytecode::kTypeOf);
209 return *this; 174 return *this;
210 } 175 }
211 176
212 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( 177 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
213 Token::Value op, Register reg, int feedback_slot) { 178 Token::Value op, Register reg, int feedback_slot) {
214 switch (op) { 179 if (op == Token::INSTANCEOF || op == Token::IN) {
215 case Token::Value::EQ: 180 Output(BytecodeForCompareOperation(op), RegisterOperand(reg));
216 Output(Bytecode::kTestEqual, RegisterOperand(reg), 181 } else {
217 UnsignedOperand(feedback_slot)); 182 Output(BytecodeForCompareOperation(op), RegisterOperand(reg),
218 break; 183 UnsignedOperand(feedback_slot));
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();
251 } 184 }
252 return *this; 185 return *this;
253 } 186 }
254 187
255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( 188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry(
256 size_t entry) { 189 size_t entry) {
257 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); 190 Output(Bytecode::kLdaConstant, UnsignedOperand(entry));
258 return *this; 191 return *this;
259 } 192 }
260 193
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 247
315 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, 248 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
316 Register to) { 249 Register to) {
317 DCHECK(from != to); 250 DCHECK(from != to);
318 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); 251 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to));
319 return *this; 252 return *this;
320 } 253 }
321 254
322 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, 255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot,
323 TypeofMode typeof_mode) { 256 TypeofMode typeof_mode) {
324 if (typeof_mode == INSIDE_TYPEOF) { 257 // TODO(rmcilroy): Potentially store typeof information in an
325 Output(Bytecode::kLdaGlobalInsideTypeof, feedback_slot); 258 // operand rather than having extra bytecodes.
326 } else { 259 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode);
327 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); 260 Output(bytecode, UnsignedOperand(feedback_slot));
328 Output(Bytecode::kLdaGlobal, UnsignedOperand(feedback_slot));
329 }
330 return *this; 261 return *this;
331 } 262 }
332 263
333 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( 264 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
334 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { 265 const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
266 Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
335 size_t name_index = GetConstantPoolEntry(name); 267 size_t name_index = GetConstantPoolEntry(name);
336 if (language_mode == SLOPPY) { 268 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
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 }
344 return *this; 269 return *this;
345 } 270 }
346 271
347 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, 272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
348 int slot_index, 273 int slot_index,
349 int depth) { 274 int depth) {
350 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), 275 Output(Bytecode::kLdaContextSlot, RegisterOperand(context),
351 UnsignedOperand(slot_index), UnsignedOperand(depth)); 276 UnsignedOperand(slot_index), UnsignedOperand(depth));
352 return *this; 277 return *this;
353 } 278 }
354 279
355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, 280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
356 int slot_index, 281 int slot_index,
357 int depth) { 282 int depth) {
358 Output(Bytecode::kStaContextSlot, RegisterOperand(context), 283 Output(Bytecode::kStaContextSlot, RegisterOperand(context),
359 UnsignedOperand(slot_index), UnsignedOperand(depth)); 284 UnsignedOperand(slot_index), UnsignedOperand(depth));
360 return *this; 285 return *this;
361 } 286 }
362 287
363 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( 288 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
364 const Handle<String> name, TypeofMode typeof_mode) { 289 const Handle<String> name, TypeofMode typeof_mode) {
290 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
291 ? Bytecode::kLdaLookupSlotInsideTypeof
292 : Bytecode::kLdaLookupSlot;
365 size_t name_index = GetConstantPoolEntry(name); 293 size_t name_index = GetConstantPoolEntry(name);
366 if (typeof_mode == INSIDE_TYPEOF) { 294 Output(bytecode, UnsignedOperand(name_index));
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 }
372 return *this; 295 return *this;
373 } 296 }
374 297
375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( 298 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot(
376 const Handle<String> name, TypeofMode typeof_mode, int slot_index, 299 const Handle<String> name, TypeofMode typeof_mode, int slot_index,
377 int depth) { 300 int depth) {
378 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) 301 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
379 ? Bytecode::kLdaLookupContextSlotInsideTypeof 302 ? Bytecode::kLdaLookupContextSlotInsideTypeof
380 : Bytecode::kLdaLookupContextSlot; 303 : Bytecode::kLdaLookupContextSlot;
381 size_t name_index = GetConstantPoolEntry(name); 304 size_t name_index = GetConstantPoolEntry(name);
382 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), 305 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index),
383 UnsignedOperand(depth)); 306 UnsignedOperand(depth));
384 return *this; 307 return *this;
385 } 308 }
386 309
387 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( 310 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot(
388 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, 311 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot,
389 int depth) { 312 int depth) {
390 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) 313 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
391 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof 314 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof
392 : Bytecode::kLdaLookupGlobalSlot; 315 : Bytecode::kLdaLookupGlobalSlot;
393 size_t name_index = GetConstantPoolEntry(name); 316 size_t name_index = GetConstantPoolEntry(name);
394 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), 317 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot),
395 UnsignedOperand(depth)); 318 UnsignedOperand(depth));
396 return *this; 319 return *this;
397 } 320 }
398 321
399 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( 322 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
400 const Handle<String> name, LanguageMode language_mode) { 323 const Handle<String> name, LanguageMode language_mode) {
324 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
401 size_t name_index = GetConstantPoolEntry(name); 325 size_t name_index = GetConstantPoolEntry(name);
402 if (language_mode == SLOPPY) { 326 Output(bytecode, UnsignedOperand(name_index));
403 Output(Bytecode::kStaLookupSlotSloppy, UnsignedOperand(name_index));
404 } else {
405 DCHECK_EQ(language_mode, STRICT);
406 Output(Bytecode::kStaLookupSlotStrict, UnsignedOperand(name_index));
407 }
408 return *this; 327 return *this;
409 } 328 }
410 329
411 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( 330 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
412 Register object, const Handle<Name> name, int feedback_slot) { 331 Register object, const Handle<Name> name, int feedback_slot) {
413 size_t name_index = GetConstantPoolEntry(name); 332 size_t name_index = GetConstantPoolEntry(name);
414 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), 333 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object),
415 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); 334 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
416 return *this; 335 return *this;
417 } 336 }
418 337
419 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( 338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
420 Register object, int feedback_slot) { 339 Register object, int feedback_slot) {
421 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), 340 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object),
422 UnsignedOperand(feedback_slot)); 341 UnsignedOperand(feedback_slot));
423 return *this; 342 return *this;
424 } 343 }
425 344
426 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( 345 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
427 Register object, const Handle<Name> name, int feedback_slot, 346 Register object, const Handle<Name> name, int feedback_slot,
428 LanguageMode language_mode) { 347 LanguageMode language_mode) {
348 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode);
429 size_t name_index = GetConstantPoolEntry(name); 349 size_t name_index = GetConstantPoolEntry(name);
430 if (language_mode == SLOPPY) { 350 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index),
431 Output(Bytecode::kStaNamedPropertySloppy, RegisterOperand(object), 351 UnsignedOperand(feedback_slot));
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 }
438 return *this; 352 return *this;
439 } 353 }
440 354
441 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( 355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
442 Register object, Register key, int feedback_slot, 356 Register object, Register key, int feedback_slot,
443 LanguageMode language_mode) { 357 LanguageMode language_mode) {
444 if (language_mode == SLOPPY) { 358 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode);
445 Output(Bytecode::kStaKeyedPropertySloppy, RegisterOperand(object), 359 Output(bytecode, RegisterOperand(object), RegisterOperand(key),
446 RegisterOperand(key), UnsignedOperand(feedback_slot)); 360 UnsignedOperand(feedback_slot));
447 } else {
448 DCHECK_EQ(language_mode, STRICT);
449 Output(Bytecode::kStaKeyedPropertyStrict, RegisterOperand(object),
450 RegisterOperand(key), UnsignedOperand(feedback_slot));
451 }
452 return *this; 361 return *this;
453 } 362 }
454 363
455 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, 364 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry,
456 int flags) { 365 int flags) {
457 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), 366 Output(Bytecode::kCreateClosure, UnsignedOperand(entry),
458 UnsignedOperand(flags)); 367 UnsignedOperand(flags));
459 return *this; 368 return *this;
460 } 369 }
461 370
(...skipping 21 matching lines...) Expand all
483 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( 392 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(
484 Register object, Handle<ScopeInfo> scope_info) { 393 Register object, Handle<ScopeInfo> scope_info) {
485 size_t scope_info_index = GetConstantPoolEntry(scope_info); 394 size_t scope_info_index = GetConstantPoolEntry(scope_info);
486 Output(Bytecode::kCreateWithContext, RegisterOperand(object), 395 Output(Bytecode::kCreateWithContext, RegisterOperand(object),
487 UnsignedOperand(scope_info_index)); 396 UnsignedOperand(scope_info_index));
488 return *this; 397 return *this;
489 } 398 }
490 399
491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( 400 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
492 CreateArgumentsType type) { 401 CreateArgumentsType type) {
493 switch (type) { 402 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather
494 case CreateArgumentsType::kMappedArguments: 403 // than having two different bytecodes once we have better support for
495 Output(Bytecode::kCreateMappedArguments); 404 // branches in the InterpreterAssembler.
496 break; 405 Bytecode bytecode = BytecodeForCreateArguments(type);
497 case CreateArgumentsType::kUnmappedArguments: 406 Output(bytecode);
498 Output(Bytecode::kCreateUnmappedArguments);
499 break;
500 case CreateArgumentsType::kRestParameter:
501 Output(Bytecode::kCreateRestParameter);
502 break;
503 default:
504 UNREACHABLE();
505 }
506 return *this; 407 return *this;
507 } 408 }
508 409
509 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( 410 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
510 Handle<String> pattern, int literal_index, int flags) { 411 Handle<String> pattern, int literal_index, int flags) {
511 size_t pattern_entry = GetConstantPoolEntry(pattern); 412 size_t pattern_entry = GetConstantPoolEntry(pattern);
512 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), 413 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry),
513 UnsignedOperand(literal_index), UnsignedOperand(flags)); 414 UnsignedOperand(literal_index), UnsignedOperand(flags));
514 return *this; 415 return *this;
515 } 416 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 return *this; 469 return *this;
569 } 470 }
570 471
571 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, 472 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
572 BytecodeLabel* label) { 473 BytecodeLabel* label) {
573 pipeline_->BindLabel(target, label); 474 pipeline_->BindLabel(target, label);
574 LeaveBasicBlock(); 475 LeaveBasicBlock();
575 return *this; 476 return *this;
576 } 477 }
577 478
479 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node,
480 BytecodeLabel* label) {
481 AttachSourceInfo(node);
482 pipeline_->WriteJump(node, label);
483 LeaveBasicBlock();
484 return *this;
485 }
486
578 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { 487 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
579 OutputJump(Bytecode::kJump, label); 488 BytecodeNode node(Bytecode::kJump, 0);
580 return *this; 489 return OutputJump(&node, label);
581 } 490 }
582 491
583 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { 492 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
584 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue 493 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue
585 // to JumpIfTrue. 494 // to JumpIfTrue.
586 OutputJump(Bytecode::kJumpIfToBooleanTrue, label); 495 BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0);
587 return *this; 496 return OutputJump(&node, label);
588 } 497 }
589 498
590 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { 499 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
591 OutputJump(Bytecode::kJumpIfToBooleanFalse, label); 500 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse
592 return *this; 501 // to JumpIfFalse.
502 BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0);
503 return OutputJump(&node, label);
593 } 504 }
594 505
595 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { 506 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
596 OutputJump(Bytecode::kJumpIfNull, label); 507 BytecodeNode node(Bytecode::kJumpIfNull, 0);
597 return *this; 508 return OutputJump(&node, label);
598 } 509 }
599 510
600 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( 511 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
601 BytecodeLabel* label) { 512 BytecodeLabel* label) {
602 OutputJump(Bytecode::kJumpIfUndefined, label); 513 BytecodeNode node(Bytecode::kJumpIfUndefined, 0);
603 return *this; 514 return OutputJump(&node, label);
604 } 515 }
605 516
606 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( 517 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
607 BytecodeLabel* label) { 518 BytecodeLabel* label) {
608 OutputJump(Bytecode::kJumpIfNotHole, label); 519 BytecodeNode node(Bytecode::kJumpIfNotHole, 0);
609 return *this; 520 return OutputJump(&node, label);
610 } 521 }
611 522
612 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, 523 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
613 int loop_depth) { 524 int loop_depth) {
614 OutputJump(Bytecode::kJumpLoop, UnsignedOperand(loop_depth), label); 525 BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth));
615 return *this; 526 return OutputJump(&node, label);
616 } 527 }
617 528
618 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { 529 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
619 if (position != kNoSourcePosition) { 530 if (position != kNoSourcePosition) {
620 // We need to attach a non-breakable source position to a stack 531 // We need to attach a non-breakable source position to a stack
621 // check, so we simply add it as expression position. There can be 532 // check, so we simply add it as expression position. There can be
622 // a prior statement position from constructs like: 533 // a prior statement position from constructs like:
623 // 534 //
624 // do var x; while (false); 535 // do var x; while (false);
625 // 536 //
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 Return(); 637 Return();
727 } 638 }
728 DCHECK(return_seen_in_block_); 639 DCHECK(return_seen_in_block_);
729 } 640 }
730 641
731 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 642 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
732 Register receiver_args, 643 Register receiver_args,
733 size_t receiver_args_count, 644 size_t receiver_args_count,
734 int feedback_slot, 645 int feedback_slot,
735 TailCallMode tail_call_mode) { 646 TailCallMode tail_call_mode) {
736 if (tail_call_mode == TailCallMode::kDisallow) { 647 Bytecode bytecode = BytecodeForCall(tail_call_mode);
737 Output(Bytecode::kCall, RegisterOperand(callable), 648 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args),
738 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), 649 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot));
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 }
746 return *this; 650 return *this;
747 } 651 }
748 652
749 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, 653 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
750 Register first_arg, 654 Register first_arg,
751 size_t arg_count, 655 size_t arg_count,
752 int feedback_slot_id) { 656 int feedback_slot_id) {
753 if (!first_arg.is_valid()) { 657 if (!first_arg.is_valid()) {
754 DCHECK_EQ(0u, arg_count); 658 DCHECK_EQ(0u, arg_count);
755 first_arg = Register(0); 659 first_arg = Register(0);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 702
799 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( 703 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
800 int context_index, Register receiver_args, size_t receiver_args_count) { 704 int context_index, Register receiver_args, size_t receiver_args_count) {
801 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), 705 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index),
802 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); 706 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count));
803 return *this; 707 return *this;
804 } 708 }
805 709
806 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 710 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
807 LanguageMode language_mode) { 711 LanguageMode language_mode) {
808 if (language_mode == SLOPPY) { 712 Output(BytecodeForDelete(language_mode), RegisterOperand(object));
809 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object));
810 } else {
811 DCHECK_EQ(language_mode, STRICT);
812 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object));
813 }
814 return *this; 713 return *this;
815 } 714 }
816 715
817 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 716 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
818 return constant_array_builder()->Insert(object); 717 return constant_array_builder()->Insert(object);
819 } 718 }
820 719
821 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { 720 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() {
822 return constant_array_builder()->AllocateEntry(); 721 return constant_array_builder()->AllocateEntry();
823 } 722 }
824 723
825 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, 724 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry,
826 Handle<Object> object) { 725 Handle<Object> object) {
827 constant_array_builder()->InsertAllocatedEntry(entry, object); 726 constant_array_builder()->InsertAllocatedEntry(entry, object);
828 } 727 }
829 728
830 void BytecodeArrayBuilder::SetReturnPosition() { 729 void BytecodeArrayBuilder::SetReturnPosition() {
831 if (return_position_ == kNoSourcePosition) return; 730 if (return_position_ == kNoSourcePosition) return;
832 latest_source_info_.MakeStatementPosition(return_position_); 731 latest_source_info_.MakeStatementPosition(return_position_);
833 } 732 }
834 733
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
835 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { 753 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
836 return temporary_register_allocator()->RegisterIsLive(reg); 754 return temporary_register_allocator()->RegisterIsLive(reg);
837 } 755 }
838 756
839 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { 757 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
840 if (!reg.is_valid()) { 758 if (!reg.is_valid()) {
841 return false; 759 return false;
842 } 760 }
843 761
844 if (reg.is_current_context() || reg.is_function_closure() || 762 if (reg.is_current_context() || reg.is_function_closure() ||
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 } 806 }
889 break; 807 break;
890 case OperandType::kRuntimeId: 808 case OperandType::kRuntimeId:
891 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > 809 if (Bytecodes::SizeForUnsignedOperand(operands[i]) >
892 OperandSize::kShort) { 810 OperandSize::kShort) {
893 return false; 811 return false;
894 } 812 }
895 break; 813 break;
896 case OperandType::kIdx: 814 case OperandType::kIdx:
897 // TODO(leszeks): Possibly split this up into constant pool indices and 815 // TODO(leszeks): Possibly split this up into constant pool indices and
898 // other indices, for checking. 816 // other indices, for checking
899 break; 817 break;
900 case OperandType::kUImm: 818 case OperandType::kUImm:
901 case OperandType::kImm: 819 case OperandType::kImm:
902 break; 820 break;
903 case OperandType::kMaybeReg: 821 case OperandType::kMaybeReg:
904 if (Register::FromOperand(operands[i]) == Register(0)) { 822 if (Register::FromOperand(operands[i]) == Register(0)) {
905 break; 823 break;
906 } 824 }
907 // Fall-through to kReg case. 825 // Fall-through to kReg case.
908 case OperandType::kReg: 826 case OperandType::kReg:
(...skipping 22 matching lines...) Expand all
931 return false; 849 return false;
932 } 850 }
933 break; 851 break;
934 } 852 }
935 } 853 }
936 } 854 }
937 855
938 return true; 856 return true;
939 } 857 }
940 858
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
941 } // namespace interpreter 1033 } // namespace interpreter
942 } // namespace internal 1034 } // namespace internal
943 } // namespace v8 1035 } // 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