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

Side by Side Diff: src/interpreter/interpreter.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase onto 3c1dc424d3f2f651ad Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/interpreter.h" 5 #include "src/interpreter/interpreter.h"
6 6
7 #include "src/ast/prettyprinter.h" 7 #include "src/ast/prettyprinter.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/factory.h" 10 #include "src/factory.h"
11 #include "src/interpreter/bytecode-generator.h" 11 #include "src/interpreter/bytecode-generator.h"
12 #include "src/interpreter/bytecodes.h" 12 #include "src/interpreter/bytecodes.h"
13 #include "src/interpreter/interpreter-assembler.h" 13 #include "src/interpreter/interpreter-assembler.h"
14 #include "src/log.h" 14 #include "src/log.h"
15 #include "src/zone.h" 15 #include "src/zone.h"
16 16
17 namespace v8 { 17 namespace v8 {
18 namespace internal { 18 namespace internal {
19 namespace interpreter { 19 namespace interpreter {
20 20
21 using compiler::Node; 21 using compiler::Node;
22 22
23 #define __ assembler-> 23 #define __ assembler->
24 24
25 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { 25 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
26 memset(&dispatch_table_, 0, sizeof(dispatch_table_)); 26 memset(dispatch_table_, 0, sizeof(dispatch_table_));
27 } 27 }
28 28
29 void Interpreter::Initialize() { 29 void Interpreter::Initialize() {
30 DCHECK(FLAG_ignition); 30 DCHECK(FLAG_ignition);
31 if (IsDispatchTableInitialized()) return; 31 if (IsDispatchTableInitialized()) return;
32 Zone zone; 32 Zone zone;
33 HandleScope scope(isolate_); 33 HandleScope scope(isolate_);
34 34
35 #define GENERATE_CODE(Name, ...) \ 35 for (uint32_t i = 0; i < kNumberOfWideVariants; ++i) {
36 { \ 36 #define GENERATE_CODE(Name, ...) \
37 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name); \ 37 { \
38 Do##Name(&assembler); \ 38 if (i == 0 || \
39 Handle<Code> code = assembler.GenerateCode(); \ 39 Bytecodes::IsBytecodeWithScalableOperands(Bytecode::k##Name)) { \
40 TraceCodegen(code, #Name); \ 40 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name, \
41 LOG_CODE_EVENT(isolate_, \ 41 1 << i); \
42 CodeCreateEvent(Logger::BYTECODE_HANDLER_TAG, \ 42 Do##Name(&assembler); \
43 AbstractCode::cast(*code), #Name)); \ 43 Handle<Code> code = assembler.GenerateCode(); \
44 dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] = *code; \ 44 TraceCodegen(code, #Name); \
45 LOG_CODE_EVENT(isolate_, \
46 CodeCreateEvent(Logger::BYTECODE_HANDLER_TAG, \
47 AbstractCode::cast(*code), #Name)); \
48 size_t index = GetDispatchTableIndex(Bytecode::k##Name, i); \
49 dispatch_table_[index] = *code; \
50 } \
45 } 51 }
46 BYTECODE_LIST(GENERATE_CODE) 52 BYTECODE_LIST(GENERATE_CODE)
47 #undef GENERATE_CODE 53 #undef GENERATE_CODE
54 }
55
56 size_t illegal_index = GetDispatchTableIndex(Bytecode::kIllegal, 0);
57 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) {
58 if (dispatch_table_[index] == nullptr) {
59 dispatch_table_[index] = dispatch_table_[illegal_index];
60 }
61 }
48 } 62 }
49 63
50 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode) { 64 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, int operand_scale) {
51 DCHECK(IsDispatchTableInitialized()); 65 DCHECK(IsDispatchTableInitialized());
52 return dispatch_table_[Bytecodes::ToByte(bytecode)]; 66 uint32_t scale = static_cast<uint32_t>(operand_scale);
67 DCHECK(base::bits::IsPowerOfTwo32(scale));
68 size_t index =
69 GetDispatchTableIndex(bytecode, base::bits::CountTrailingZeros32(scale));
70 Code* handler = dispatch_table_[index];
71 Code* invalid_handler =
72 dispatch_table_[Bytecodes::ToByte(Bytecode::kIllegal)];
73 if (handler != invalid_handler ||
74 (operand_scale == 1 && bytecode <= Bytecode::kLast)) {
75 return handler;
76 } else {
77 return nullptr;
78 }
79 }
80
81 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode,
82 uint32_t operand_scale_log2) {
83 static const int kEntriesPerOperandScale = kMaxUInt8 + 1;
84 size_t index = operand_scale_log2 * kEntriesPerOperandScale +
85 static_cast<size_t>(bytecode);
86 DCHECK_LE(index, arraysize(dispatch_table_));
87 return index;
53 } 88 }
54 89
55 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { 90 void Interpreter::IterateDispatchTable(ObjectVisitor* v) {
56 v->VisitPointers( 91 v->VisitPointers(
57 reinterpret_cast<Object**>(&dispatch_table_[0]), 92 reinterpret_cast<Object**>(&dispatch_table_[0]),
58 reinterpret_cast<Object**>(&dispatch_table_[0] + kDispatchTableSize)); 93 reinterpret_cast<Object**>(&dispatch_table_[0] + kDispatchTableSize));
59 } 94 }
60 95
61 // static 96 // static
62 int Interpreter::InterruptBudget() { 97 int Interpreter::InterruptBudget() {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 163
129 // LdaZero 164 // LdaZero
130 // 165 //
131 // Load literal '0' into the accumulator. 166 // Load literal '0' into the accumulator.
132 void Interpreter::DoLdaZero(InterpreterAssembler* assembler) { 167 void Interpreter::DoLdaZero(InterpreterAssembler* assembler) {
133 Node* zero_value = __ NumberConstant(0.0); 168 Node* zero_value = __ NumberConstant(0.0);
134 __ SetAccumulator(zero_value); 169 __ SetAccumulator(zero_value);
135 __ Dispatch(); 170 __ Dispatch();
136 } 171 }
137 172
138 173 // LdaSmi <imm>
139 // LdaSmi8 <imm8>
140 // 174 //
141 // Load an 8-bit integer literal into the accumulator as a Smi. 175 // Load an integer literal into the accumulator as a Smi.
142 void Interpreter::DoLdaSmi8(InterpreterAssembler* assembler) { 176 void Interpreter::DoLdaSmi(InterpreterAssembler* assembler) {
143 Node* raw_int = __ BytecodeOperandImm(0); 177 Node* raw_int = __ BytecodeOperandImm(0);
144 Node* smi_int = __ SmiTag(raw_int); 178 Node* smi_int = __ SmiTag(raw_int);
145 __ SetAccumulator(smi_int); 179 __ SetAccumulator(smi_int);
146 __ Dispatch(); 180 __ Dispatch();
147 } 181 }
148 182
149 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { 183 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) {
150 Node* index = __ BytecodeOperandIdx(0); 184 Node* index = __ BytecodeOperandIdx(0);
151 Node* constant = __ LoadConstantPoolEntry(index); 185 Node* constant = __ LoadConstantPoolEntry(index);
152 __ SetAccumulator(constant); 186 __ SetAccumulator(constant);
153 __ Dispatch(); 187 __ Dispatch();
154 } 188 }
155 189
156 190
157 // LdaConstant <idx> 191 // LdaConstant <idx>
158 // 192 //
159 // Load constant literal at |idx| in the constant pool into the accumulator. 193 // Load constant literal at |idx| in the constant pool into the accumulator.
160 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { 194 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
161 DoLoadConstant(assembler); 195 DoLoadConstant(assembler);
162 } 196 }
163 197
164
165 // LdaConstantWide <idx>
166 //
167 // Load constant literal at |idx| in the constant pool into the accumulator.
168 void Interpreter::DoLdaConstantWide(InterpreterAssembler* assembler) {
169 DoLoadConstant(assembler);
170 }
171
172
173 // LdaUndefined 198 // LdaUndefined
174 // 199 //
175 // Load Undefined into the accumulator. 200 // Load Undefined into the accumulator.
176 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { 201 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
177 Node* undefined_value = 202 Node* undefined_value =
178 __ HeapConstant(isolate_->factory()->undefined_value()); 203 __ HeapConstant(isolate_->factory()->undefined_value());
179 __ SetAccumulator(undefined_value); 204 __ SetAccumulator(undefined_value);
180 __ Dispatch(); 205 __ Dispatch();
181 } 206 }
182 207
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Stores the value of register <src> to register <dst>. 273 // Stores the value of register <src> to register <dst>.
249 void Interpreter::DoMov(InterpreterAssembler* assembler) { 274 void Interpreter::DoMov(InterpreterAssembler* assembler) {
250 Node* src_index = __ BytecodeOperandReg(0); 275 Node* src_index = __ BytecodeOperandReg(0);
251 Node* src_value = __ LoadRegister(src_index); 276 Node* src_value = __ LoadRegister(src_index);
252 Node* dst_index = __ BytecodeOperandReg(1); 277 Node* dst_index = __ BytecodeOperandReg(1);
253 __ StoreRegister(src_value, dst_index); 278 __ StoreRegister(src_value, dst_index);
254 __ Dispatch(); 279 __ Dispatch();
255 } 280 }
256 281
257 282
258 // MovWide <src> <dst>
259 //
260 // Stores the value of register <src> to register <dst>.
261 void Interpreter::DoMovWide(InterpreterAssembler* assembler) {
262 DoMov(assembler);
263 }
264
265 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { 283 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) {
266 // Get the global object. 284 // Get the global object.
267 Node* context = __ GetContext(); 285 Node* context = __ GetContext();
268 Node* native_context = 286 Node* native_context =
269 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); 287 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
270 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); 288 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
271 289
272 // Load the global via the LoadIC. 290 // Load the global via the LoadIC.
273 Node* code_target = __ HeapConstant(ic.code()); 291 Node* code_target = __ HeapConstant(ic.code());
274 Node* constant_index = __ BytecodeOperandIdx(0); 292 Node* constant_index = __ BytecodeOperandIdx(0);
(...skipping 20 matching lines...) Expand all
295 // LdaGlobalInsideTypeof <name_index> <slot> 313 // LdaGlobalInsideTypeof <name_index> <slot>
296 // 314 //
297 // Load the global with name in constant pool entry <name_index> into the 315 // Load the global with name in constant pool entry <name_index> into the
298 // accumulator using FeedBackVector slot <slot> inside of a typeof. 316 // accumulator using FeedBackVector slot <slot> inside of a typeof.
299 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { 317 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
300 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF, 318 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
301 UNINITIALIZED); 319 UNINITIALIZED);
302 DoLoadGlobal(ic, assembler); 320 DoLoadGlobal(ic, assembler);
303 } 321 }
304 322
305 // LdaGlobalWide <name_index> <slot>
306 //
307 // Load the global with name in constant pool entry <name_index> into the
308 // accumulator using FeedBackVector slot <slot> outside of a typeof.
309 void Interpreter::DoLdaGlobalWide(InterpreterAssembler* assembler) {
310 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
311 UNINITIALIZED);
312 DoLoadGlobal(ic, assembler);
313 }
314
315 // LdaGlobalInsideTypeofWide <name_index> <slot>
316 //
317 // Load the global with name in constant pool entry <name_index> into the
318 // accumulator using FeedBackVector slot <slot> inside of a typeof.
319 void Interpreter::DoLdaGlobalInsideTypeofWide(InterpreterAssembler* assembler) {
320 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
321 UNINITIALIZED);
322 DoLoadGlobal(ic, assembler);
323 }
324
325
326 void Interpreter::DoStoreGlobal(Callable ic, InterpreterAssembler* assembler) { 323 void Interpreter::DoStoreGlobal(Callable ic, InterpreterAssembler* assembler) {
327 // Get the global object. 324 // Get the global object.
328 Node* context = __ GetContext(); 325 Node* context = __ GetContext();
329 Node* native_context = 326 Node* native_context =
330 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); 327 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
331 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); 328 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
332 329
333 // Store the global via the StoreIC. 330 // Store the global via the StoreIC.
334 Node* code_target = __ HeapConstant(ic.code()); 331 Node* code_target = __ HeapConstant(ic.code());
335 Node* constant_index = __ BytecodeOperandIdx(0); 332 Node* constant_index = __ BytecodeOperandIdx(0);
336 Node* name = __ LoadConstantPoolEntry(constant_index); 333 Node* name = __ LoadConstantPoolEntry(constant_index);
337 Node* value = __ GetAccumulator(); 334 Node* value = __ GetAccumulator();
338 Node* raw_slot = __ BytecodeOperandIdx(1); 335 Node* raw_slot = __ BytecodeOperandIdx(1);
339 Node* smi_slot = __ SmiTag(raw_slot); 336 Node* smi_slot = __ SmiTag(raw_slot);
340 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 337 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
341 __ CallStub(ic.descriptor(), code_target, context, global, name, value, 338 __ CallStub(ic.descriptor(), code_target, context, global, name, value,
342 smi_slot, type_feedback_vector); 339 smi_slot, type_feedback_vector);
343
344 __ Dispatch(); 340 __ Dispatch();
345 } 341 }
346 342
347 343
348 // StaGlobalSloppy <name_index> <slot> 344 // StaGlobalSloppy <name_index> <slot>
349 // 345 //
350 // Store the value in the accumulator into the global with name in constant pool 346 // Store the value in the accumulator into the global with name in constant pool
351 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. 347 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
352 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { 348 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
353 Callable ic = 349 Callable ic =
354 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); 350 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
355 DoStoreGlobal(ic, assembler); 351 DoStoreGlobal(ic, assembler);
356 } 352 }
357 353
358 354
359 // StaGlobalStrict <name_index> <slot> 355 // StaGlobalStrict <name_index> <slot>
360 // 356 //
361 // Store the value in the accumulator into the global with name in constant pool 357 // Store the value in the accumulator into the global with name in constant pool
362 // entry <name_index> using FeedBackVector slot <slot> in strict mode. 358 // entry <name_index> using FeedBackVector slot <slot> in strict mode.
363 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { 359 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
364 Callable ic = 360 Callable ic =
365 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 361 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
366 DoStoreGlobal(ic, assembler); 362 DoStoreGlobal(ic, assembler);
367 } 363 }
368 364
369
370 // StaGlobalSloppyWide <name_index> <slot>
371 //
372 // Store the value in the accumulator into the global with name in constant pool
373 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
374 void Interpreter::DoStaGlobalSloppyWide(InterpreterAssembler* assembler) {
375 Callable ic =
376 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
377 DoStoreGlobal(ic, assembler);
378 }
379
380
381 // StaGlobalStrictWide <name_index> <slot>
382 //
383 // Store the value in the accumulator into the global with name in constant pool
384 // entry <name_index> using FeedBackVector slot <slot> in strict mode.
385 void Interpreter::DoStaGlobalStrictWide(InterpreterAssembler* assembler) {
386 Callable ic =
387 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
388 DoStoreGlobal(ic, assembler);
389 }
390
391
392 // LdaContextSlot <context> <slot_index> 365 // LdaContextSlot <context> <slot_index>
393 // 366 //
394 // Load the object in |slot_index| of |context| into the accumulator. 367 // Load the object in |slot_index| of |context| into the accumulator.
395 void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) { 368 void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
396 Node* reg_index = __ BytecodeOperandReg(0); 369 Node* reg_index = __ BytecodeOperandReg(0);
397 Node* context = __ LoadRegister(reg_index); 370 Node* context = __ LoadRegister(reg_index);
398 Node* slot_index = __ BytecodeOperandIdx(1); 371 Node* slot_index = __ BytecodeOperandIdx(1);
399 Node* result = __ LoadContextSlot(context, slot_index); 372 Node* result = __ LoadContextSlot(context, slot_index);
400 __ SetAccumulator(result); 373 __ SetAccumulator(result);
401 __ Dispatch(); 374 __ Dispatch();
402 } 375 }
403 376
404
405 // LdaContextSlotWide <context> <slot_index>
406 //
407 // Load the object in |slot_index| of |context| into the accumulator.
408 void Interpreter::DoLdaContextSlotWide(InterpreterAssembler* assembler) {
409 DoLdaContextSlot(assembler);
410 }
411
412
413 // StaContextSlot <context> <slot_index> 377 // StaContextSlot <context> <slot_index>
414 // 378 //
415 // Stores the object in the accumulator into |slot_index| of |context|. 379 // Stores the object in the accumulator into |slot_index| of |context|.
416 void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) { 380 void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) {
417 Node* value = __ GetAccumulator(); 381 Node* value = __ GetAccumulator();
418 Node* reg_index = __ BytecodeOperandReg(0); 382 Node* reg_index = __ BytecodeOperandReg(0);
419 Node* context = __ LoadRegister(reg_index); 383 Node* context = __ LoadRegister(reg_index);
420 Node* slot_index = __ BytecodeOperandIdx(1); 384 Node* slot_index = __ BytecodeOperandIdx(1);
421 __ StoreContextSlot(context, slot_index, value); 385 __ StoreContextSlot(context, slot_index, value);
422 __ Dispatch(); 386 __ Dispatch();
423 } 387 }
424 388
425
426 // StaContextSlot <context> <slot_index>
427 //
428 // Stores the object in the accumulator into |slot_index| of |context|.
429 void Interpreter::DoStaContextSlotWide(InterpreterAssembler* assembler) {
430 DoStaContextSlot(assembler);
431 }
432
433 void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id, 389 void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id,
434 InterpreterAssembler* assembler) { 390 InterpreterAssembler* assembler) {
435 Node* index = __ BytecodeOperandIdx(0); 391 Node* index = __ BytecodeOperandIdx(0);
436 Node* name = __ LoadConstantPoolEntry(index); 392 Node* name = __ LoadConstantPoolEntry(index);
437 Node* context = __ GetContext(); 393 Node* context = __ GetContext();
438 Node* result = __ CallRuntime(function_id, context, name); 394 Node* result = __ CallRuntime(function_id, context, name);
439 __ SetAccumulator(result); 395 __ SetAccumulator(result);
440 __ Dispatch(); 396 __ Dispatch();
441 } 397 }
442 398
443
444 // LdaLookupSlot <name_index> 399 // LdaLookupSlot <name_index>
445 // 400 //
446 // Lookup the object with the name in constant pool entry |name_index| 401 // Lookup the object with the name in constant pool entry |name_index|
447 // dynamically. 402 // dynamically.
448 void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) { 403 void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) {
449 DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler); 404 DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler);
450 } 405 }
451 406
452
453 // LdaLookupSlotInsideTypeof <name_index> 407 // LdaLookupSlotInsideTypeof <name_index>
454 // 408 //
455 // Lookup the object with the name in constant pool entry |name_index| 409 // Lookup the object with the name in constant pool entry |name_index|
456 // dynamically without causing a NoReferenceError. 410 // dynamically without causing a NoReferenceError.
457 void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) { 411 void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) {
458 DoLoadLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); 412 DoLoadLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
459 } 413 }
460 414
461
462 // LdaLookupSlotWide <name_index>
463 //
464 // Lookup the object with the name in constant pool entry |name_index|
465 // dynamically.
466 void Interpreter::DoLdaLookupSlotWide(InterpreterAssembler* assembler) {
467 DoLdaLookupSlot(assembler);
468 }
469
470
471 // LdaLookupSlotInsideTypeofWide <name_index>
472 //
473 // Lookup the object with the name in constant pool entry |name_index|
474 // dynamically without causing a NoReferenceError.
475 void Interpreter::DoLdaLookupSlotInsideTypeofWide(
476 InterpreterAssembler* assembler) {
477 DoLdaLookupSlotInsideTypeof(assembler);
478 }
479
480 void Interpreter::DoStoreLookupSlot(LanguageMode language_mode, 415 void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
481 InterpreterAssembler* assembler) { 416 InterpreterAssembler* assembler) {
482 Node* value = __ GetAccumulator(); 417 Node* value = __ GetAccumulator();
483 Node* index = __ BytecodeOperandIdx(0); 418 Node* index = __ BytecodeOperandIdx(0);
484 Node* name = __ LoadConstantPoolEntry(index); 419 Node* name = __ LoadConstantPoolEntry(index);
485 Node* context = __ GetContext(); 420 Node* context = __ GetContext();
486 Node* result = __ CallRuntime(is_strict(language_mode) 421 Node* result = __ CallRuntime(is_strict(language_mode)
487 ? Runtime::kStoreLookupSlot_Strict 422 ? Runtime::kStoreLookupSlot_Strict
488 : Runtime::kStoreLookupSlot_Sloppy, 423 : Runtime::kStoreLookupSlot_Sloppy,
489 context, name, value); 424 context, name, value);
490 __ SetAccumulator(result); 425 __ SetAccumulator(result);
491 __ Dispatch(); 426 __ Dispatch();
492 } 427 }
493 428
494
495 // StaLookupSlotSloppy <name_index> 429 // StaLookupSlotSloppy <name_index>
496 // 430 //
497 // Store the object in accumulator to the object with the name in constant 431 // Store the object in accumulator to the object with the name in constant
498 // pool entry |name_index| in sloppy mode. 432 // pool entry |name_index| in sloppy mode.
499 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { 433 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
500 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); 434 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler);
501 } 435 }
502 436
503 437
504 // StaLookupSlotStrict <name_index> 438 // StaLookupSlotStrict <name_index>
505 // 439 //
506 // Store the object in accumulator to the object with the name in constant 440 // Store the object in accumulator to the object with the name in constant
507 // pool entry |name_index| in strict mode. 441 // pool entry |name_index| in strict mode.
508 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { 442 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
509 DoStoreLookupSlot(LanguageMode::STRICT, assembler); 443 DoStoreLookupSlot(LanguageMode::STRICT, assembler);
510 } 444 }
511 445
512
513 // StaLookupSlotSloppyWide <name_index>
514 //
515 // Store the object in accumulator to the object with the name in constant
516 // pool entry |name_index| in sloppy mode.
517 void Interpreter::DoStaLookupSlotSloppyWide(InterpreterAssembler* assembler) {
518 DoStaLookupSlotSloppy(assembler);
519 }
520
521
522 // StaLookupSlotStrictWide <name_index>
523 //
524 // Store the object in accumulator to the object with the name in constant
525 // pool entry |name_index| in strict mode.
526 void Interpreter::DoStaLookupSlotStrictWide(InterpreterAssembler* assembler) {
527 DoStaLookupSlotStrict(assembler);
528 }
529
530 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { 446 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) {
531 Node* code_target = __ HeapConstant(ic.code()); 447 Node* code_target = __ HeapConstant(ic.code());
532 Node* register_index = __ BytecodeOperandReg(0); 448 Node* register_index = __ BytecodeOperandReg(0);
533 Node* object = __ LoadRegister(register_index); 449 Node* object = __ LoadRegister(register_index);
534 Node* constant_index = __ BytecodeOperandIdx(1); 450 Node* constant_index = __ BytecodeOperandIdx(1);
535 Node* name = __ LoadConstantPoolEntry(constant_index); 451 Node* name = __ LoadConstantPoolEntry(constant_index);
536 Node* raw_slot = __ BytecodeOperandIdx(2); 452 Node* raw_slot = __ BytecodeOperandIdx(2);
537 Node* smi_slot = __ SmiTag(raw_slot); 453 Node* smi_slot = __ SmiTag(raw_slot);
538 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 454 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
539 Node* context = __ GetContext(); 455 Node* context = __ GetContext();
540 Node* result = __ CallStub(ic.descriptor(), code_target, context, object, 456 Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
541 name, smi_slot, type_feedback_vector); 457 name, smi_slot, type_feedback_vector);
542 __ SetAccumulator(result); 458 __ SetAccumulator(result);
543 __ Dispatch(); 459 __ Dispatch();
544 } 460 }
545 461
546 // LoadIC <object> <name_index> <slot> 462 // LoadIC <object> <name_index> <slot>
547 // 463 //
548 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at 464 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
549 // constant pool entry <name_index>. 465 // constant pool entry <name_index>.
550 void Interpreter::DoLoadIC(InterpreterAssembler* assembler) { 466 void Interpreter::DoLoadIC(InterpreterAssembler* assembler) {
551 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, 467 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
552 UNINITIALIZED); 468 UNINITIALIZED);
553 DoLoadIC(ic, assembler); 469 DoLoadIC(ic, assembler);
554 } 470 }
555 471
556 // LoadICWide <object> <name_index> <slot>
557 //
558 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
559 // constant pool entry <name_index>.
560 void Interpreter::DoLoadICWide(InterpreterAssembler* assembler) {
561 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
562 UNINITIALIZED);
563 DoLoadIC(ic, assembler);
564 }
565
566
567 void Interpreter::DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler) { 472 void Interpreter::DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler) {
568 Node* code_target = __ HeapConstant(ic.code()); 473 Node* code_target = __ HeapConstant(ic.code());
569 Node* reg_index = __ BytecodeOperandReg(0); 474 Node* reg_index = __ BytecodeOperandReg(0);
570 Node* object = __ LoadRegister(reg_index); 475 Node* object = __ LoadRegister(reg_index);
571 Node* name = __ GetAccumulator(); 476 Node* name = __ GetAccumulator();
572 Node* raw_slot = __ BytecodeOperandIdx(1); 477 Node* raw_slot = __ BytecodeOperandIdx(1);
573 Node* smi_slot = __ SmiTag(raw_slot); 478 Node* smi_slot = __ SmiTag(raw_slot);
574 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 479 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
575 Node* context = __ GetContext(); 480 Node* context = __ GetContext();
576 Node* result = __ CallStub(ic.descriptor(), code_target, context, object, 481 Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
577 name, smi_slot, type_feedback_vector); 482 name, smi_slot, type_feedback_vector);
578 __ SetAccumulator(result); 483 __ SetAccumulator(result);
579 __ Dispatch(); 484 __ Dispatch();
580 } 485 }
581 486
582 // KeyedLoadIC <object> <slot> 487 // KeyedLoadIC <object> <slot>
583 // 488 //
584 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key 489 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
585 // in the accumulator. 490 // in the accumulator.
586 void Interpreter::DoKeyedLoadIC(InterpreterAssembler* assembler) { 491 void Interpreter::DoKeyedLoadIC(InterpreterAssembler* assembler) {
587 Callable ic = 492 Callable ic =
588 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED); 493 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED);
589 DoKeyedLoadIC(ic, assembler); 494 DoKeyedLoadIC(ic, assembler);
590 } 495 }
591 496
592 // KeyedLoadICWide <object> <slot>
593 //
594 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
595 // in the accumulator.
596 void Interpreter::DoKeyedLoadICWide(InterpreterAssembler* assembler) {
597 Callable ic =
598 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED);
599 DoKeyedLoadIC(ic, assembler);
600 }
601
602
603 void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) { 497 void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) {
604 Node* code_target = __ HeapConstant(ic.code()); 498 Node* code_target = __ HeapConstant(ic.code());
605 Node* object_reg_index = __ BytecodeOperandReg(0); 499 Node* object_reg_index = __ BytecodeOperandReg(0);
606 Node* object = __ LoadRegister(object_reg_index); 500 Node* object = __ LoadRegister(object_reg_index);
607 Node* constant_index = __ BytecodeOperandIdx(1); 501 Node* constant_index = __ BytecodeOperandIdx(1);
608 Node* name = __ LoadConstantPoolEntry(constant_index); 502 Node* name = __ LoadConstantPoolEntry(constant_index);
609 Node* value = __ GetAccumulator(); 503 Node* value = __ GetAccumulator();
610 Node* raw_slot = __ BytecodeOperandIdx(2); 504 Node* raw_slot = __ BytecodeOperandIdx(2);
611 Node* smi_slot = __ SmiTag(raw_slot); 505 Node* smi_slot = __ SmiTag(raw_slot);
612 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 506 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
(...skipping 20 matching lines...) Expand all
633 // 527 //
634 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and 528 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
635 // the name in constant pool entry <name_index> with the value in the 529 // the name in constant pool entry <name_index> with the value in the
636 // accumulator. 530 // accumulator.
637 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { 531 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) {
638 Callable ic = 532 Callable ic =
639 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 533 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
640 DoStoreIC(ic, assembler); 534 DoStoreIC(ic, assembler);
641 } 535 }
642 536
643
644 // StoreICSloppyWide <object> <name_index> <slot>
645 //
646 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
647 // the name in constant pool entry <name_index> with the value in the
648 // accumulator.
649 void Interpreter::DoStoreICSloppyWide(InterpreterAssembler* assembler) {
650 Callable ic =
651 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
652 DoStoreIC(ic, assembler);
653 }
654
655
656 // StoreICStrictWide <object> <name_index> <slot>
657 //
658 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
659 // the name in constant pool entry <name_index> with the value in the
660 // accumulator.
661 void Interpreter::DoStoreICStrictWide(InterpreterAssembler* assembler) {
662 Callable ic =
663 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
664 DoStoreIC(ic, assembler);
665 }
666
667 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { 537 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) {
668 Node* code_target = __ HeapConstant(ic.code()); 538 Node* code_target = __ HeapConstant(ic.code());
669 Node* object_reg_index = __ BytecodeOperandReg(0); 539 Node* object_reg_index = __ BytecodeOperandReg(0);
670 Node* object = __ LoadRegister(object_reg_index); 540 Node* object = __ LoadRegister(object_reg_index);
671 Node* name_reg_index = __ BytecodeOperandReg(1); 541 Node* name_reg_index = __ BytecodeOperandReg(1);
672 Node* name = __ LoadRegister(name_reg_index); 542 Node* name = __ LoadRegister(name_reg_index);
673 Node* value = __ GetAccumulator(); 543 Node* value = __ GetAccumulator();
674 Node* raw_slot = __ BytecodeOperandIdx(2); 544 Node* raw_slot = __ BytecodeOperandIdx(2);
675 Node* smi_slot = __ SmiTag(raw_slot); 545 Node* smi_slot = __ SmiTag(raw_slot);
676 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 546 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
(...skipping 18 matching lines...) Expand all
695 // KeyedStoreICStore <object> <key> <slot> 565 // KeyedStoreICStore <object> <key> <slot>
696 // 566 //
697 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> 567 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
698 // and the key <key> with the value in the accumulator. 568 // and the key <key> with the value in the accumulator.
699 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { 569 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) {
700 Callable ic = 570 Callable ic =
701 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 571 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
702 DoKeyedStoreIC(ic, assembler); 572 DoKeyedStoreIC(ic, assembler);
703 } 573 }
704 574
705
706 // KeyedStoreICSloppyWide <object> <key> <slot>
707 //
708 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
709 // and the key <key> with the value in the accumulator.
710 void Interpreter::DoKeyedStoreICSloppyWide(InterpreterAssembler* assembler) {
711 Callable ic =
712 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
713 DoKeyedStoreIC(ic, assembler);
714 }
715
716
717 // KeyedStoreICStoreWide <object> <key> <slot>
718 //
719 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
720 // and the key <key> with the value in the accumulator.
721 void Interpreter::DoKeyedStoreICStrictWide(InterpreterAssembler* assembler) {
722 Callable ic =
723 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
724 DoKeyedStoreIC(ic, assembler);
725 }
726
727 // PushContext <context> 575 // PushContext <context>
728 // 576 //
729 // Saves the current context in <context>, and pushes the accumulator as the 577 // Saves the current context in <context>, and pushes the accumulator as the
730 // new current context. 578 // new current context.
731 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { 579 void Interpreter::DoPushContext(InterpreterAssembler* assembler) {
732 Node* reg_index = __ BytecodeOperandReg(0); 580 Node* reg_index = __ BytecodeOperandReg(0);
733 Node* new_context = __ GetAccumulator(); 581 Node* new_context = __ GetAccumulator();
734 Node* old_context = __ GetContext(); 582 Node* old_context = __ GetContext();
735 __ StoreRegister(old_context, reg_index); 583 __ StoreRegister(old_context, reg_index);
736 __ SetContext(new_context); 584 __ SetContext(new_context);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 838
991 839
992 // Call <callable> <receiver> <arg_count> 840 // Call <callable> <receiver> <arg_count>
993 // 841 //
994 // Call a JSfunction or Callable in |callable| with the |receiver| and 842 // Call a JSfunction or Callable in |callable| with the |receiver| and
995 // |arg_count| arguments in subsequent registers. 843 // |arg_count| arguments in subsequent registers.
996 void Interpreter::DoCall(InterpreterAssembler* assembler) { 844 void Interpreter::DoCall(InterpreterAssembler* assembler) {
997 DoJSCall(assembler, TailCallMode::kDisallow); 845 DoJSCall(assembler, TailCallMode::kDisallow);
998 } 846 }
999 847
1000
1001 // CallWide <callable> <receiver> <arg_count>
1002 //
1003 // Call a JSfunction or Callable in |callable| with the |receiver| and
1004 // |arg_count| arguments in subsequent registers.
1005 void Interpreter::DoCallWide(InterpreterAssembler* assembler) {
1006 DoJSCall(assembler, TailCallMode::kDisallow);
1007 }
1008
1009 // TailCall <callable> <receiver> <arg_count> 848 // TailCall <callable> <receiver> <arg_count>
1010 // 849 //
1011 // Tail call a JSfunction or Callable in |callable| with the |receiver| and 850 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
1012 // |arg_count| arguments in subsequent registers. 851 // |arg_count| arguments in subsequent registers.
1013 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { 852 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
1014 DoJSCall(assembler, TailCallMode::kAllow); 853 DoJSCall(assembler, TailCallMode::kAllow);
1015 } 854 }
1016 855
1017 // TailCallWide <callable> <receiver> <arg_count>
1018 //
1019 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
1020 // |arg_count| arguments in subsequent registers.
1021 void Interpreter::DoTailCallWide(InterpreterAssembler* assembler) {
1022 DoJSCall(assembler, TailCallMode::kAllow);
1023 }
1024
1025 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { 856 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
1026 Node* function_id = __ BytecodeOperandIdx(0); 857 Node* function_id = __ BytecodeOperandRuntimeId(0);
1027 Node* first_arg_reg = __ BytecodeOperandReg(1); 858 Node* first_arg_reg = __ BytecodeOperandReg(1);
1028 Node* first_arg = __ RegisterLocation(first_arg_reg); 859 Node* first_arg = __ RegisterLocation(first_arg_reg);
1029 Node* args_count = __ BytecodeOperandCount(2); 860 Node* args_count = __ BytecodeOperandCount(2);
1030 Node* context = __ GetContext(); 861 Node* context = __ GetContext();
1031 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); 862 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count);
1032 __ SetAccumulator(result); 863 __ SetAccumulator(result);
1033 __ Dispatch(); 864 __ Dispatch();
1034 } 865 }
1035 866
1036 867
1037 // CallRuntime <function_id> <first_arg> <arg_count> 868 // CallRuntime <function_id> <first_arg> <arg_count>
1038 // 869 //
1039 // Call the runtime function |function_id| with the first argument in 870 // Call the runtime function |function_id| with the first argument in
1040 // register |first_arg| and |arg_count| arguments in subsequent 871 // register |first_arg| and |arg_count| arguments in subsequent
1041 // registers. 872 // registers.
1042 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { 873 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
1043 DoCallRuntimeCommon(assembler); 874 DoCallRuntimeCommon(assembler);
1044 } 875 }
1045 876
1046
1047 // CallRuntime <function_id> <first_arg> <arg_count>
1048 //
1049 // Call the runtime function |function_id| with the first argument in
1050 // register |first_arg| and |arg_count| arguments in subsequent
1051 // registers.
1052 void Interpreter::DoCallRuntimeWide(InterpreterAssembler* assembler) {
1053 DoCallRuntimeCommon(assembler);
1054 }
1055
1056 void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) { 877 void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) {
1057 // Call the runtime function. 878 // Call the runtime function.
1058 Node* function_id = __ BytecodeOperandIdx(0); 879 Node* function_id = __ BytecodeOperandRuntimeId(0);
1059 Node* first_arg_reg = __ BytecodeOperandReg(1); 880 Node* first_arg_reg = __ BytecodeOperandReg(1);
1060 Node* first_arg = __ RegisterLocation(first_arg_reg); 881 Node* first_arg = __ RegisterLocation(first_arg_reg);
1061 Node* args_count = __ BytecodeOperandCount(2); 882 Node* args_count = __ BytecodeOperandCount(2);
1062 Node* context = __ GetContext(); 883 Node* context = __ GetContext();
1063 Node* result_pair = 884 Node* result_pair =
1064 __ CallRuntimeN(function_id, context, first_arg, args_count, 2); 885 __ CallRuntimeN(function_id, context, first_arg, args_count, 2);
1065 886
1066 // Store the results in <first_return> and <first_return + 1> 887 // Store the results in <first_return> and <first_return + 1>
1067 Node* first_return_reg = __ BytecodeOperandReg(3); 888 Node* first_return_reg = __ BytecodeOperandReg(3);
1068 Node* second_return_reg = __ NextRegister(first_return_reg); 889 Node* second_return_reg = __ NextRegister(first_return_reg);
1069 Node* result0 = __ Projection(0, result_pair); 890 Node* result0 = __ Projection(0, result_pair);
1070 Node* result1 = __ Projection(1, result_pair); 891 Node* result1 = __ Projection(1, result_pair);
1071 __ StoreRegister(result0, first_return_reg); 892 __ StoreRegister(result0, first_return_reg);
1072 __ StoreRegister(result1, second_return_reg); 893 __ StoreRegister(result1, second_return_reg);
1073 __ Dispatch(); 894 __ Dispatch();
1074 } 895 }
1075 896
1076 897
1077 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> 898 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
1078 // 899 //
1079 // Call the runtime function |function_id| which returns a pair, with the 900 // Call the runtime function |function_id| which returns a pair, with the
1080 // first argument in register |first_arg| and |arg_count| arguments in 901 // first argument in register |first_arg| and |arg_count| arguments in
1081 // subsequent registers. Returns the result in <first_return> and 902 // subsequent registers. Returns the result in <first_return> and
1082 // <first_return + 1> 903 // <first_return + 1>
1083 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { 904 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
1084 DoCallRuntimeForPairCommon(assembler); 905 DoCallRuntimeForPairCommon(assembler);
1085 } 906 }
1086 907
1087
1088 // CallRuntimeForPairWide <function_id> <first_arg> <arg_count> <first_return>
1089 //
1090 // Call the runtime function |function_id| which returns a pair, with the
1091 // first argument in register |first_arg| and |arg_count| arguments in
1092 // subsequent registers. Returns the result in <first_return> and
1093 // <first_return + 1>
1094 void Interpreter::DoCallRuntimeForPairWide(InterpreterAssembler* assembler) {
1095 DoCallRuntimeForPairCommon(assembler);
1096 }
1097
1098 void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) { 908 void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) {
1099 Node* context_index = __ BytecodeOperandIdx(0); 909 Node* context_index = __ BytecodeOperandIdx(0);
1100 Node* receiver_reg = __ BytecodeOperandReg(1); 910 Node* receiver_reg = __ BytecodeOperandReg(1);
1101 Node* first_arg = __ RegisterLocation(receiver_reg); 911 Node* first_arg = __ RegisterLocation(receiver_reg);
1102 Node* receiver_args_count = __ BytecodeOperandCount(2); 912 Node* receiver_args_count = __ BytecodeOperandCount(2);
1103 Node* receiver_count = __ Int32Constant(1); 913 Node* receiver_count = __ Int32Constant(1);
1104 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); 914 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
1105 915
1106 // Get the function to call from the native context. 916 // Get the function to call from the native context.
1107 Node* context = __ GetContext(); 917 Node* context = __ GetContext();
(...skipping 10 matching lines...) Expand all
1118 928
1119 929
1120 // CallJSRuntime <context_index> <receiver> <arg_count> 930 // CallJSRuntime <context_index> <receiver> <arg_count>
1121 // 931 //
1122 // Call the JS runtime function that has the |context_index| with the receiver 932 // Call the JS runtime function that has the |context_index| with the receiver
1123 // in register |receiver| and |arg_count| arguments in subsequent registers. 933 // in register |receiver| and |arg_count| arguments in subsequent registers.
1124 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { 934 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
1125 DoCallJSRuntimeCommon(assembler); 935 DoCallJSRuntimeCommon(assembler);
1126 } 936 }
1127 937
1128
1129 // CallJSRuntimeWide <context_index> <receiver> <arg_count>
1130 //
1131 // Call the JS runtime function that has the |context_index| with the receiver
1132 // in register |receiver| and |arg_count| arguments in subsequent registers.
1133 void Interpreter::DoCallJSRuntimeWide(InterpreterAssembler* assembler) {
1134 DoCallJSRuntimeCommon(assembler);
1135 }
1136
1137 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { 938 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
1138 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); 939 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
1139 Node* new_target = __ GetAccumulator(); 940 Node* new_target = __ GetAccumulator();
1140 Node* constructor_reg = __ BytecodeOperandReg(0); 941 Node* constructor_reg = __ BytecodeOperandReg(0);
1141 Node* constructor = __ LoadRegister(constructor_reg); 942 Node* constructor = __ LoadRegister(constructor_reg);
1142 Node* first_arg_reg = __ BytecodeOperandReg(1); 943 Node* first_arg_reg = __ BytecodeOperandReg(1);
1143 Node* first_arg = __ RegisterLocation(first_arg_reg); 944 Node* first_arg = __ RegisterLocation(first_arg_reg);
1144 Node* args_count = __ BytecodeOperandCount(2); 945 Node* args_count = __ BytecodeOperandCount(2);
1145 Node* context = __ GetContext(); 946 Node* context = __ GetContext();
1146 Node* result = 947 Node* result =
1147 __ CallConstruct(constructor, context, new_target, first_arg, args_count); 948 __ CallConstruct(constructor, context, new_target, first_arg, args_count);
1148 __ SetAccumulator(result); 949 __ SetAccumulator(result);
1149 __ Dispatch(); 950 __ Dispatch();
1150 } 951 }
1151 952
1152 953
1153 // New <constructor> <first_arg> <arg_count> 954 // New <constructor> <first_arg> <arg_count>
1154 // 955 //
1155 // Call operator new with |constructor| and the first argument in 956 // Call operator new with |constructor| and the first argument in
1156 // register |first_arg| and |arg_count| arguments in subsequent 957 // register |first_arg| and |arg_count| arguments in subsequent
1157 // registers. The new.target is in the accumulator. 958 // registers. The new.target is in the accumulator.
1158 // 959 //
1159 void Interpreter::DoNew(InterpreterAssembler* assembler) { 960 void Interpreter::DoNew(InterpreterAssembler* assembler) {
1160 DoCallConstruct(assembler); 961 DoCallConstruct(assembler);
1161 } 962 }
1162 963
1163
1164 // NewWide <constructor> <first_arg> <arg_count>
1165 //
1166 // Call operator new with |constructor| and the first argument in
1167 // register |first_arg| and |arg_count| arguments in subsequent
1168 // registers. The new.target is in the accumulator.
1169 //
1170 void Interpreter::DoNewWide(InterpreterAssembler* assembler) {
1171 DoCallConstruct(assembler);
1172 }
1173
1174
1175 // TestEqual <src> 964 // TestEqual <src>
1176 // 965 //
1177 // Test if the value in the <src> register equals the accumulator. 966 // Test if the value in the <src> register equals the accumulator.
1178 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { 967 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
1179 DoBinaryOp(Runtime::kEqual, assembler); 968 DoBinaryOp(Runtime::kEqual, assembler);
1180 } 969 }
1181 970
1182 971
1183 // TestNotEqual <src> 972 // TestNotEqual <src>
1184 // 973 //
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 } 1063 }
1275 1064
1276 1065
1277 // ToObject 1066 // ToObject
1278 // 1067 //
1279 // Cast the object referenced by the accumulator to a JSObject. 1068 // Cast the object referenced by the accumulator to a JSObject.
1280 void Interpreter::DoToObject(InterpreterAssembler* assembler) { 1069 void Interpreter::DoToObject(InterpreterAssembler* assembler) {
1281 DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler); 1070 DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler);
1282 } 1071 }
1283 1072
1284 1073 // Jump <imm>
1285 // Jump <imm8>
1286 // 1074 //
1287 // Jump by number of bytes represented by the immediate operand |imm8|. 1075 // Jump by number of bytes represented by the immediate operand |imm|.
1288 void Interpreter::DoJump(InterpreterAssembler* assembler) { 1076 void Interpreter::DoJump(InterpreterAssembler* assembler) {
1289 Node* relative_jump = __ BytecodeOperandImm(0); 1077 Node* relative_jump = __ BytecodeOperandImm(0);
1290 __ Jump(relative_jump); 1078 __ Jump(relative_jump);
1291 } 1079 }
1292 1080
1293 1081 // JumpConstant <idx>
1294 // JumpConstant <idx8>
1295 // 1082 //
1296 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool. 1083 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool.
1297 void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) { 1084 void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
1298 Node* index = __ BytecodeOperandIdx(0); 1085 Node* index = __ BytecodeOperandIdx(0);
1299 Node* constant = __ LoadConstantPoolEntry(index); 1086 Node* constant = __ LoadConstantPoolEntry(index);
1300 Node* relative_jump = __ SmiUntag(constant); 1087 Node* relative_jump = __ SmiUntag(constant);
1301 __ Jump(relative_jump); 1088 __ Jump(relative_jump);
1302 } 1089 }
1303 1090
1304 1091 // JumpIfTrue <imm>
1305 // JumpConstantWide <idx16>
1306 //
1307 // Jump by number of bytes in the Smi in the |idx16| entry in the
1308 // constant pool.
1309 void Interpreter::DoJumpConstantWide(InterpreterAssembler* assembler) {
1310 DoJumpConstant(assembler);
1311 }
1312
1313
1314 // JumpIfTrue <imm8>
1315 // 1092 //
1316 // Jump by number of bytes represented by an immediate operand if the 1093 // Jump by number of bytes represented by an immediate operand if the
1317 // accumulator contains true. 1094 // accumulator contains true.
1318 void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) { 1095 void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
1319 Node* accumulator = __ GetAccumulator(); 1096 Node* accumulator = __ GetAccumulator();
1320 Node* relative_jump = __ BytecodeOperandImm(0); 1097 Node* relative_jump = __ BytecodeOperandImm(0);
1321 Node* true_value = __ BooleanConstant(true); 1098 Node* true_value = __ BooleanConstant(true);
1322 __ JumpIfWordEqual(accumulator, true_value, relative_jump); 1099 __ JumpIfWordEqual(accumulator, true_value, relative_jump);
1323 } 1100 }
1324 1101
1325 1102 // JumpIfTrueConstant <idx>
1326 // JumpIfTrueConstant <idx8>
1327 // 1103 //
1328 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1104 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1329 // if the accumulator contains true. 1105 // if the accumulator contains true.
1330 void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) { 1106 void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
1331 Node* accumulator = __ GetAccumulator(); 1107 Node* accumulator = __ GetAccumulator();
1332 Node* index = __ BytecodeOperandIdx(0); 1108 Node* index = __ BytecodeOperandIdx(0);
1333 Node* constant = __ LoadConstantPoolEntry(index); 1109 Node* constant = __ LoadConstantPoolEntry(index);
1334 Node* relative_jump = __ SmiUntag(constant); 1110 Node* relative_jump = __ SmiUntag(constant);
1335 Node* true_value = __ BooleanConstant(true); 1111 Node* true_value = __ BooleanConstant(true);
1336 __ JumpIfWordEqual(accumulator, true_value, relative_jump); 1112 __ JumpIfWordEqual(accumulator, true_value, relative_jump);
1337 } 1113 }
1338 1114
1339 1115 // JumpIfFalse <imm>
1340 // JumpIfTrueConstantWide <idx16>
1341 //
1342 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1343 // if the accumulator contains true.
1344 void Interpreter::DoJumpIfTrueConstantWide(InterpreterAssembler* assembler) {
1345 DoJumpIfTrueConstant(assembler);
1346 }
1347
1348
1349 // JumpIfFalse <imm8>
1350 // 1116 //
1351 // Jump by number of bytes represented by an immediate operand if the 1117 // Jump by number of bytes represented by an immediate operand if the
1352 // accumulator contains false. 1118 // accumulator contains false.
1353 void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) { 1119 void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
1354 Node* accumulator = __ GetAccumulator(); 1120 Node* accumulator = __ GetAccumulator();
1355 Node* relative_jump = __ BytecodeOperandImm(0); 1121 Node* relative_jump = __ BytecodeOperandImm(0);
1356 Node* false_value = __ BooleanConstant(false); 1122 Node* false_value = __ BooleanConstant(false);
1357 __ JumpIfWordEqual(accumulator, false_value, relative_jump); 1123 __ JumpIfWordEqual(accumulator, false_value, relative_jump);
1358 } 1124 }
1359 1125
1360 1126 // JumpIfFalseConstant <idx>
1361 // JumpIfFalseConstant <idx8>
1362 // 1127 //
1363 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1128 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1364 // if the accumulator contains false. 1129 // if the accumulator contains false.
1365 void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) { 1130 void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
1366 Node* accumulator = __ GetAccumulator(); 1131 Node* accumulator = __ GetAccumulator();
1367 Node* index = __ BytecodeOperandIdx(0); 1132 Node* index = __ BytecodeOperandIdx(0);
1368 Node* constant = __ LoadConstantPoolEntry(index); 1133 Node* constant = __ LoadConstantPoolEntry(index);
1369 Node* relative_jump = __ SmiUntag(constant); 1134 Node* relative_jump = __ SmiUntag(constant);
1370 Node* false_value = __ BooleanConstant(false); 1135 Node* false_value = __ BooleanConstant(false);
1371 __ JumpIfWordEqual(accumulator, false_value, relative_jump); 1136 __ JumpIfWordEqual(accumulator, false_value, relative_jump);
1372 } 1137 }
1373 1138
1374 1139 // JumpIfToBooleanTrue <imm>
1375 // JumpIfFalseConstant <idx16>
1376 //
1377 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1378 // if the accumulator contains false.
1379 void Interpreter::DoJumpIfFalseConstantWide(InterpreterAssembler* assembler) {
1380 DoJumpIfFalseConstant(assembler);
1381 }
1382
1383
1384 // JumpIfToBooleanTrue <imm8>
1385 // 1140 //
1386 // Jump by number of bytes represented by an immediate operand if the object 1141 // Jump by number of bytes represented by an immediate operand if the object
1387 // referenced by the accumulator is true when the object is cast to boolean. 1142 // referenced by the accumulator is true when the object is cast to boolean.
1388 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { 1143 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
1389 Callable callable = CodeFactory::ToBoolean(isolate_); 1144 Callable callable = CodeFactory::ToBoolean(isolate_);
1390 Node* target = __ HeapConstant(callable.code()); 1145 Node* target = __ HeapConstant(callable.code());
1391 Node* accumulator = __ GetAccumulator(); 1146 Node* accumulator = __ GetAccumulator();
1392 Node* context = __ GetContext(); 1147 Node* context = __ GetContext();
1393 Node* to_boolean_value = 1148 Node* to_boolean_value =
1394 __ CallStub(callable.descriptor(), target, context, accumulator); 1149 __ CallStub(callable.descriptor(), target, context, accumulator);
1395 Node* relative_jump = __ BytecodeOperandImm(0); 1150 Node* relative_jump = __ BytecodeOperandImm(0);
1396 Node* true_value = __ BooleanConstant(true); 1151 Node* true_value = __ BooleanConstant(true);
1397 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); 1152 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1398 } 1153 }
1399 1154
1400 1155 // JumpIfToBooleanTrueConstant <idx>
1401 // JumpIfToBooleanTrueConstant <idx8>
1402 // 1156 //
1403 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1157 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1404 // if the object referenced by the accumulator is true when the object is cast 1158 // if the object referenced by the accumulator is true when the object is cast
1405 // to boolean. 1159 // to boolean.
1406 void Interpreter::DoJumpIfToBooleanTrueConstant( 1160 void Interpreter::DoJumpIfToBooleanTrueConstant(
1407 InterpreterAssembler* assembler) { 1161 InterpreterAssembler* assembler) {
1408 Callable callable = CodeFactory::ToBoolean(isolate_); 1162 Callable callable = CodeFactory::ToBoolean(isolate_);
1409 Node* target = __ HeapConstant(callable.code()); 1163 Node* target = __ HeapConstant(callable.code());
1410 Node* accumulator = __ GetAccumulator(); 1164 Node* accumulator = __ GetAccumulator();
1411 Node* context = __ GetContext(); 1165 Node* context = __ GetContext();
1412 Node* to_boolean_value = 1166 Node* to_boolean_value =
1413 __ CallStub(callable.descriptor(), target, context, accumulator); 1167 __ CallStub(callable.descriptor(), target, context, accumulator);
1414 Node* index = __ BytecodeOperandIdx(0); 1168 Node* index = __ BytecodeOperandIdx(0);
1415 Node* constant = __ LoadConstantPoolEntry(index); 1169 Node* constant = __ LoadConstantPoolEntry(index);
1416 Node* relative_jump = __ SmiUntag(constant); 1170 Node* relative_jump = __ SmiUntag(constant);
1417 Node* true_value = __ BooleanConstant(true); 1171 Node* true_value = __ BooleanConstant(true);
1418 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); 1172 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1419 } 1173 }
1420 1174
1421 1175 // JumpIfToBooleanFalse <imm>
1422 // JumpIfToBooleanTrueConstantWide <idx16>
1423 //
1424 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1425 // if the object referenced by the accumulator is true when the object is cast
1426 // to boolean.
1427 void Interpreter::DoJumpIfToBooleanTrueConstantWide(
1428 InterpreterAssembler* assembler) {
1429 DoJumpIfToBooleanTrueConstant(assembler);
1430 }
1431
1432
1433 // JumpIfToBooleanFalse <imm8>
1434 // 1176 //
1435 // Jump by number of bytes represented by an immediate operand if the object 1177 // Jump by number of bytes represented by an immediate operand if the object
1436 // referenced by the accumulator is false when the object is cast to boolean. 1178 // referenced by the accumulator is false when the object is cast to boolean.
1437 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { 1179 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
1438 Callable callable = CodeFactory::ToBoolean(isolate_); 1180 Callable callable = CodeFactory::ToBoolean(isolate_);
1439 Node* target = __ HeapConstant(callable.code()); 1181 Node* target = __ HeapConstant(callable.code());
1440 Node* accumulator = __ GetAccumulator(); 1182 Node* accumulator = __ GetAccumulator();
1441 Node* context = __ GetContext(); 1183 Node* context = __ GetContext();
1442 Node* to_boolean_value = 1184 Node* to_boolean_value =
1443 __ CallStub(callable.descriptor(), target, context, accumulator); 1185 __ CallStub(callable.descriptor(), target, context, accumulator);
1444 Node* relative_jump = __ BytecodeOperandImm(0); 1186 Node* relative_jump = __ BytecodeOperandImm(0);
1445 Node* false_value = __ BooleanConstant(false); 1187 Node* false_value = __ BooleanConstant(false);
1446 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); 1188 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1447 } 1189 }
1448 1190
1449 1191 // JumpIfToBooleanFalseConstant <idx>
1450 // JumpIfToBooleanFalseConstant <idx8>
1451 // 1192 //
1452 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1193 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1453 // if the object referenced by the accumulator is false when the object is cast 1194 // if the object referenced by the accumulator is false when the object is cast
1454 // to boolean. 1195 // to boolean.
1455 void Interpreter::DoJumpIfToBooleanFalseConstant( 1196 void Interpreter::DoJumpIfToBooleanFalseConstant(
1456 InterpreterAssembler* assembler) { 1197 InterpreterAssembler* assembler) {
1457 Callable callable = CodeFactory::ToBoolean(isolate_); 1198 Callable callable = CodeFactory::ToBoolean(isolate_);
1458 Node* target = __ HeapConstant(callable.code()); 1199 Node* target = __ HeapConstant(callable.code());
1459 Node* accumulator = __ GetAccumulator(); 1200 Node* accumulator = __ GetAccumulator();
1460 Node* context = __ GetContext(); 1201 Node* context = __ GetContext();
1461 Node* to_boolean_value = 1202 Node* to_boolean_value =
1462 __ CallStub(callable.descriptor(), target, context, accumulator); 1203 __ CallStub(callable.descriptor(), target, context, accumulator);
1463 Node* index = __ BytecodeOperandIdx(0); 1204 Node* index = __ BytecodeOperandIdx(0);
1464 Node* constant = __ LoadConstantPoolEntry(index); 1205 Node* constant = __ LoadConstantPoolEntry(index);
1465 Node* relative_jump = __ SmiUntag(constant); 1206 Node* relative_jump = __ SmiUntag(constant);
1466 Node* false_value = __ BooleanConstant(false); 1207 Node* false_value = __ BooleanConstant(false);
1467 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); 1208 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1468 } 1209 }
1469 1210
1470 1211 // JumpIfNull <imm>
1471 // JumpIfToBooleanFalseConstantWide <idx16>
1472 //
1473 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1474 // if the object referenced by the accumulator is false when the object is cast
1475 // to boolean.
1476 void Interpreter::DoJumpIfToBooleanFalseConstantWide(
1477 InterpreterAssembler* assembler) {
1478 DoJumpIfToBooleanFalseConstant(assembler);
1479 }
1480
1481
1482 // JumpIfNull <imm8>
1483 // 1212 //
1484 // Jump by number of bytes represented by an immediate operand if the object 1213 // Jump by number of bytes represented by an immediate operand if the object
1485 // referenced by the accumulator is the null constant. 1214 // referenced by the accumulator is the null constant.
1486 void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) { 1215 void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) {
1487 Node* accumulator = __ GetAccumulator(); 1216 Node* accumulator = __ GetAccumulator();
1488 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); 1217 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
1489 Node* relative_jump = __ BytecodeOperandImm(0); 1218 Node* relative_jump = __ BytecodeOperandImm(0);
1490 __ JumpIfWordEqual(accumulator, null_value, relative_jump); 1219 __ JumpIfWordEqual(accumulator, null_value, relative_jump);
1491 } 1220 }
1492 1221
1493 1222 // JumpIfNullConstant <idx>
1494 // JumpIfNullConstant <idx8>
1495 // 1223 //
1496 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1224 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1497 // if the object referenced by the accumulator is the null constant. 1225 // if the object referenced by the accumulator is the null constant.
1498 void Interpreter::DoJumpIfNullConstant(InterpreterAssembler* assembler) { 1226 void Interpreter::DoJumpIfNullConstant(InterpreterAssembler* assembler) {
1499 Node* accumulator = __ GetAccumulator(); 1227 Node* accumulator = __ GetAccumulator();
1500 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); 1228 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
1501 Node* index = __ BytecodeOperandIdx(0); 1229 Node* index = __ BytecodeOperandIdx(0);
1502 Node* constant = __ LoadConstantPoolEntry(index); 1230 Node* constant = __ LoadConstantPoolEntry(index);
1503 Node* relative_jump = __ SmiUntag(constant); 1231 Node* relative_jump = __ SmiUntag(constant);
1504 __ JumpIfWordEqual(accumulator, null_value, relative_jump); 1232 __ JumpIfWordEqual(accumulator, null_value, relative_jump);
1505 } 1233 }
1506 1234
1507 1235 // JumpIfUndefined <imm>
1508 // JumpIfNullConstantWide <idx16>
1509 //
1510 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1511 // if the object referenced by the accumulator is the null constant.
1512 void Interpreter::DoJumpIfNullConstantWide(InterpreterAssembler* assembler) {
1513 DoJumpIfNullConstant(assembler);
1514 }
1515
1516 // JumpIfUndefined <imm8>
1517 // 1236 //
1518 // Jump by number of bytes represented by an immediate operand if the object 1237 // Jump by number of bytes represented by an immediate operand if the object
1519 // referenced by the accumulator is the undefined constant. 1238 // referenced by the accumulator is the undefined constant.
1520 void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) { 1239 void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) {
1521 Node* accumulator = __ GetAccumulator(); 1240 Node* accumulator = __ GetAccumulator();
1522 Node* undefined_value = 1241 Node* undefined_value =
1523 __ HeapConstant(isolate_->factory()->undefined_value()); 1242 __ HeapConstant(isolate_->factory()->undefined_value());
1524 Node* relative_jump = __ BytecodeOperandImm(0); 1243 Node* relative_jump = __ BytecodeOperandImm(0);
1525 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump); 1244 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
1526 } 1245 }
1527 1246
1528 1247 // JumpIfUndefinedConstant <idx>
1529 // JumpIfUndefinedConstant <idx8>
1530 // 1248 //
1531 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1249 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1532 // if the object referenced by the accumulator is the undefined constant. 1250 // if the object referenced by the accumulator is the undefined constant.
1533 void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) { 1251 void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) {
1534 Node* accumulator = __ GetAccumulator(); 1252 Node* accumulator = __ GetAccumulator();
1535 Node* undefined_value = 1253 Node* undefined_value =
1536 __ HeapConstant(isolate_->factory()->undefined_value()); 1254 __ HeapConstant(isolate_->factory()->undefined_value());
1537 Node* index = __ BytecodeOperandIdx(0); 1255 Node* index = __ BytecodeOperandIdx(0);
1538 Node* constant = __ LoadConstantPoolEntry(index); 1256 Node* constant = __ LoadConstantPoolEntry(index);
1539 Node* relative_jump = __ SmiUntag(constant); 1257 Node* relative_jump = __ SmiUntag(constant);
1540 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump); 1258 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
1541 } 1259 }
1542 1260
1543 1261 // JumpIfNotHole <imm>
1544 // JumpIfUndefinedConstantWide <idx16>
1545 //
1546 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1547 // if the object referenced by the accumulator is the undefined constant.
1548 void Interpreter::DoJumpIfUndefinedConstantWide(
1549 InterpreterAssembler* assembler) {
1550 DoJumpIfUndefinedConstant(assembler);
1551 }
1552
1553 // JumpIfNotHole <imm8>
1554 // 1262 //
1555 // Jump by number of bytes represented by an immediate operand if the object 1263 // Jump by number of bytes represented by an immediate operand if the object
1556 // referenced by the accumulator is the hole. 1264 // referenced by the accumulator is the hole.
1557 void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) { 1265 void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) {
1558 Node* accumulator = __ GetAccumulator(); 1266 Node* accumulator = __ GetAccumulator();
1559 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); 1267 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
1560 Node* relative_jump = __ BytecodeOperandImm(0); 1268 Node* relative_jump = __ BytecodeOperandImm(0);
1561 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump); 1269 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
1562 } 1270 }
1563 1271
1564 // JumpIfNotHoleConstant <idx8> 1272 // JumpIfNotHoleConstant <idx>
1565 // 1273 //
1566 // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool 1274 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1567 // if the object referenced by the accumulator is the hole constant. 1275 // if the object referenced by the accumulator is the hole constant.
1568 void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) { 1276 void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) {
1569 Node* accumulator = __ GetAccumulator(); 1277 Node* accumulator = __ GetAccumulator();
1570 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); 1278 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
1571 Node* index = __ BytecodeOperandIdx(0); 1279 Node* index = __ BytecodeOperandIdx(0);
1572 Node* constant = __ LoadConstantPoolEntry(index); 1280 Node* constant = __ LoadConstantPoolEntry(index);
1573 Node* relative_jump = __ SmiUntag(constant); 1281 Node* relative_jump = __ SmiUntag(constant);
1574 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump); 1282 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
1575 } 1283 }
1576 1284
1577 // JumpIfNotHoleConstantWide <idx16>
1578 //
1579 // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1580 // if the object referenced by the accumulator is the hole constant.
1581 void Interpreter::DoJumpIfNotHoleConstantWide(InterpreterAssembler* assembler) {
1582 DoJumpIfNotHoleConstant(assembler);
1583 }
1584
1585 void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, 1285 void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
1586 InterpreterAssembler* assembler) { 1286 InterpreterAssembler* assembler) {
1587 Node* index = __ BytecodeOperandIdx(0); 1287 Node* index = __ BytecodeOperandIdx(0);
1588 Node* constant_elements = __ LoadConstantPoolEntry(index); 1288 Node* constant_elements = __ LoadConstantPoolEntry(index);
1589 Node* literal_index_raw = __ BytecodeOperandIdx(1); 1289 Node* literal_index_raw = __ BytecodeOperandIdx(1);
1590 Node* literal_index = __ SmiTag(literal_index_raw); 1290 Node* literal_index = __ SmiTag(literal_index_raw);
1591 Node* flags_raw = __ BytecodeOperandImm(2); 1291 Node* flags_raw = __ BytecodeOperandFlag(2);
1592 Node* flags = __ SmiTag(flags_raw); 1292 Node* flags = __ SmiTag(flags_raw);
1593 Node* closure = __ LoadRegister(Register::function_closure()); 1293 Node* closure = __ LoadRegister(Register::function_closure());
1594 Node* context = __ GetContext(); 1294 Node* context = __ GetContext();
1595 Node* result = __ CallRuntime(function_id, context, closure, literal_index, 1295 Node* result = __ CallRuntime(function_id, context, closure, literal_index,
1596 constant_elements, flags); 1296 constant_elements, flags);
1597 __ SetAccumulator(result); 1297 __ SetAccumulator(result);
1598 __ Dispatch(); 1298 __ Dispatch();
1599 } 1299 }
1600 1300
1601 1301
1602 // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags> 1302 // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
1603 // 1303 //
1604 // Creates a regular expression literal for literal index <literal_idx> with 1304 // Creates a regular expression literal for literal index <literal_idx> with
1605 // <flags> and the pattern in <pattern_idx>. 1305 // <flags> and the pattern in <pattern_idx>.
1606 void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) { 1306 void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) {
1607 Callable callable = CodeFactory::FastCloneRegExp(isolate_); 1307 Callable callable = CodeFactory::FastCloneRegExp(isolate_);
1608 Node* target = __ HeapConstant(callable.code()); 1308 Node* target = __ HeapConstant(callable.code());
1609 Node* index = __ BytecodeOperandIdx(0); 1309 Node* index = __ BytecodeOperandIdx(0);
1610 Node* pattern = __ LoadConstantPoolEntry(index); 1310 Node* pattern = __ LoadConstantPoolEntry(index);
1611 Node* literal_index_raw = __ BytecodeOperandIdx(1); 1311 Node* literal_index_raw = __ BytecodeOperandIdx(1);
1612 Node* literal_index = __ SmiTag(literal_index_raw); 1312 Node* literal_index = __ SmiTag(literal_index_raw);
1613 Node* flags_raw = __ BytecodeOperandImm(2); 1313 Node* flags_raw = __ BytecodeOperandFlag(2);
1614 Node* flags = __ SmiTag(flags_raw); 1314 Node* flags = __ SmiTag(flags_raw);
1615 Node* closure = __ LoadRegister(Register::function_closure()); 1315 Node* closure = __ LoadRegister(Register::function_closure());
1616 Node* context = __ GetContext(); 1316 Node* context = __ GetContext();
1617 Node* result = __ CallStub(callable.descriptor(), target, context, closure, 1317 Node* result = __ CallStub(callable.descriptor(), target, context, closure,
1618 literal_index, pattern, flags); 1318 literal_index, pattern, flags);
1619 __ SetAccumulator(result); 1319 __ SetAccumulator(result);
1620 __ Dispatch(); 1320 __ Dispatch();
1621 } 1321 }
1622 1322
1623
1624 // CreateRegExpLiteralWide <pattern_idx> <literal_idx> <flags>
1625 //
1626 // Creates a regular expression literal for literal index <literal_idx> with
1627 // <flags> and the pattern in <pattern_idx>.
1628 void Interpreter::DoCreateRegExpLiteralWide(InterpreterAssembler* assembler) {
1629 DoCreateRegExpLiteral(assembler);
1630 }
1631
1632
1633 // CreateArrayLiteral <element_idx> <literal_idx> <flags> 1323 // CreateArrayLiteral <element_idx> <literal_idx> <flags>
1634 // 1324 //
1635 // Creates an array literal for literal index <literal_idx> with flags <flags> 1325 // Creates an array literal for literal index <literal_idx> with flags <flags>
1636 // and constant elements in <element_idx>. 1326 // and constant elements in <element_idx>.
1637 void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) { 1327 void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) {
1638 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler); 1328 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
1639 } 1329 }
1640 1330
1641
1642 // CreateArrayLiteralWide <element_idx> <literal_idx> <flags>
1643 //
1644 // Creates an array literal for literal index <literal_idx> with flags <flags>
1645 // and constant elements in <element_idx>.
1646 void Interpreter::DoCreateArrayLiteralWide(InterpreterAssembler* assembler) {
1647 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
1648 }
1649
1650
1651 // CreateObjectLiteral <element_idx> <literal_idx> <flags> 1331 // CreateObjectLiteral <element_idx> <literal_idx> <flags>
1652 // 1332 //
1653 // Creates an object literal for literal index <literal_idx> with flags <flags> 1333 // Creates an object literal for literal index <literal_idx> with flags <flags>
1654 // and constant elements in <element_idx>. 1334 // and constant elements in <element_idx>.
1655 void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) { 1335 void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) {
1656 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler); 1336 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
1657 } 1337 }
1658 1338
1659
1660 // CreateObjectLiteralWide <element_idx> <literal_idx> <flags>
1661 //
1662 // Creates an object literal for literal index <literal_idx> with flags <flags>
1663 // and constant elements in <element_idx>.
1664 void Interpreter::DoCreateObjectLiteralWide(InterpreterAssembler* assembler) {
1665 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
1666 }
1667
1668
1669 // CreateClosure <index> <tenured> 1339 // CreateClosure <index> <tenured>
1670 // 1340 //
1671 // Creates a new closure for SharedFunctionInfo at position |index| in the 1341 // Creates a new closure for SharedFunctionInfo at position |index| in the
1672 // constant pool and with the PretenureFlag <tenured>. 1342 // constant pool and with the PretenureFlag <tenured>.
1673 void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) { 1343 void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
1674 // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of 1344 // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of
1675 // calling into the runtime. 1345 // calling into the runtime.
1676 Node* index = __ BytecodeOperandIdx(0); 1346 Node* index = __ BytecodeOperandIdx(0);
1677 Node* shared = __ LoadConstantPoolEntry(index); 1347 Node* shared = __ LoadConstantPoolEntry(index);
1678 Node* tenured_raw = __ BytecodeOperandImm(1); 1348 Node* tenured_raw = __ BytecodeOperandFlag(1);
1679 Node* tenured = __ SmiTag(tenured_raw); 1349 Node* tenured = __ SmiTag(tenured_raw);
1680 Node* context = __ GetContext(); 1350 Node* context = __ GetContext();
1681 Node* result = 1351 Node* result =
1682 __ CallRuntime(Runtime::kInterpreterNewClosure, context, shared, tenured); 1352 __ CallRuntime(Runtime::kInterpreterNewClosure, context, shared, tenured);
1683 __ SetAccumulator(result); 1353 __ SetAccumulator(result);
1684 __ Dispatch(); 1354 __ Dispatch();
1685 } 1355 }
1686 1356
1687
1688 // CreateClosureWide <index> <tenured>
1689 //
1690 // Creates a new closure for SharedFunctionInfo at position |index| in the
1691 // constant pool and with the PretenureFlag <tenured>.
1692 void Interpreter::DoCreateClosureWide(InterpreterAssembler* assembler) {
1693 return DoCreateClosure(assembler);
1694 }
1695
1696
1697 // CreateMappedArguments 1357 // CreateMappedArguments
1698 // 1358 //
1699 // Creates a new mapped arguments object. 1359 // Creates a new mapped arguments object.
1700 void Interpreter::DoCreateMappedArguments(InterpreterAssembler* assembler) { 1360 void Interpreter::DoCreateMappedArguments(InterpreterAssembler* assembler) {
1701 Node* closure = __ LoadRegister(Register::function_closure()); 1361 Node* closure = __ LoadRegister(Register::function_closure());
1702 Node* context = __ GetContext(); 1362 Node* context = __ GetContext();
1703 Node* result = 1363 Node* result =
1704 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); 1364 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
1705 __ SetAccumulator(result); 1365 __ SetAccumulator(result);
1706 __ Dispatch(); 1366 __ Dispatch();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 // 0 == cache_type, 1 == cache_array, 2 == cache_length 1468 // 0 == cache_type, 1 == cache_array, 2 == cache_length
1809 Node* output_register = __ BytecodeOperandReg(0); 1469 Node* output_register = __ BytecodeOperandReg(0);
1810 for (int i = 0; i < 3; i++) { 1470 for (int i = 0; i < 3; i++) {
1811 Node* cache_info = __ Projection(i, result_triple); 1471 Node* cache_info = __ Projection(i, result_triple);
1812 __ StoreRegister(cache_info, output_register); 1472 __ StoreRegister(cache_info, output_register);
1813 output_register = __ NextRegister(output_register); 1473 output_register = __ NextRegister(output_register);
1814 } 1474 }
1815 __ Dispatch(); 1475 __ Dispatch();
1816 } 1476 }
1817 1477
1818
1819 // ForInPrepareWide <cache_info_triple>
1820 //
1821 // Returns state for for..in loop execution based on the object in the
1822 // accumulator. The result is output in registers |cache_info_triple| to
1823 // |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
1824 // and cache_length respectively.
1825 void Interpreter::DoForInPrepareWide(InterpreterAssembler* assembler) {
1826 DoForInPrepare(assembler);
1827 }
1828
1829
1830 // ForInNext <receiver> <index> <cache_info_pair> 1478 // ForInNext <receiver> <index> <cache_info_pair>
1831 // 1479 //
1832 // Returns the next enumerable property in the the accumulator. 1480 // Returns the next enumerable property in the the accumulator.
1833 void Interpreter::DoForInNext(InterpreterAssembler* assembler) { 1481 void Interpreter::DoForInNext(InterpreterAssembler* assembler) {
1834 Node* receiver_reg = __ BytecodeOperandReg(0); 1482 Node* receiver_reg = __ BytecodeOperandReg(0);
1835 Node* receiver = __ LoadRegister(receiver_reg); 1483 Node* receiver = __ LoadRegister(receiver_reg);
1836 Node* index_reg = __ BytecodeOperandReg(1); 1484 Node* index_reg = __ BytecodeOperandReg(1);
1837 Node* index = __ LoadRegister(index_reg); 1485 Node* index = __ LoadRegister(index_reg);
1838 Node* cache_type_reg = __ BytecodeOperandReg(2); 1486 Node* cache_type_reg = __ BytecodeOperandReg(2);
1839 Node* cache_type = __ LoadRegister(cache_type_reg); 1487 Node* cache_type = __ LoadRegister(cache_type_reg);
(...skipping 26 matching lines...) Expand all
1866 1514
1867 // Need to filter the {key} for the {receiver}. 1515 // Need to filter the {key} for the {receiver}.
1868 Node* context = __ GetContext(); 1516 Node* context = __ GetContext();
1869 Node* result = 1517 Node* result =
1870 __ CallRuntime(Runtime::kForInFilter, context, receiver, key); 1518 __ CallRuntime(Runtime::kForInFilter, context, receiver, key);
1871 __ SetAccumulator(result); 1519 __ SetAccumulator(result);
1872 __ Dispatch(); 1520 __ Dispatch();
1873 } 1521 }
1874 } 1522 }
1875 1523
1876
1877 // ForInNextWide <receiver> <index> <cache_info_pair>
1878 //
1879 // Returns the next enumerable property in the the accumulator.
1880 void Interpreter::DoForInNextWide(InterpreterAssembler* assembler) {
1881 return DoForInNext(assembler);
1882 }
1883
1884
1885 // ForInDone <index> <cache_length> 1524 // ForInDone <index> <cache_length>
1886 // 1525 //
1887 // Returns true if the end of the enumerable properties has been reached. 1526 // Returns true if the end of the enumerable properties has been reached.
1888 void Interpreter::DoForInDone(InterpreterAssembler* assembler) { 1527 void Interpreter::DoForInDone(InterpreterAssembler* assembler) {
1889 // TODO(oth): Implement directly rather than making a runtime call. 1528 // TODO(oth): Implement directly rather than making a runtime call.
1890 Node* index_reg = __ BytecodeOperandReg(0); 1529 Node* index_reg = __ BytecodeOperandReg(0);
1891 Node* index = __ LoadRegister(index_reg); 1530 Node* index = __ LoadRegister(index_reg);
1892 Node* cache_length_reg = __ BytecodeOperandReg(1); 1531 Node* cache_length_reg = __ BytecodeOperandReg(1);
1893 Node* cache_length = __ LoadRegister(cache_length_reg); 1532 Node* cache_length = __ LoadRegister(cache_length_reg);
1894 Node* context = __ GetContext(); 1533 Node* context = __ GetContext();
1895 Node* result = 1534 Node* result =
1896 __ CallRuntime(Runtime::kForInDone, context, index, cache_length); 1535 __ CallRuntime(Runtime::kForInDone, context, index, cache_length);
1897 __ SetAccumulator(result); 1536 __ SetAccumulator(result);
1898 __ Dispatch(); 1537 __ Dispatch();
1899 } 1538 }
1900 1539
1901
1902 // ForInStep <index> 1540 // ForInStep <index>
1903 // 1541 //
1904 // Increments the loop counter in register |index| and stores the result 1542 // Increments the loop counter in register |index| and stores the result
1905 // in the accumulator. 1543 // in the accumulator.
1906 void Interpreter::DoForInStep(InterpreterAssembler* assembler) { 1544 void Interpreter::DoForInStep(InterpreterAssembler* assembler) {
1907 Node* index_reg = __ BytecodeOperandReg(0); 1545 Node* index_reg = __ BytecodeOperandReg(0);
1908 Node* index = __ LoadRegister(index_reg); 1546 Node* index = __ LoadRegister(index_reg);
1909 Node* one = __ SmiConstant(Smi::FromInt(1)); 1547 Node* one = __ SmiConstant(Smi::FromInt(1));
1910 Node* result = __ SmiAdd(index, one); 1548 Node* result = __ SmiAdd(index, one);
1911 __ SetAccumulator(result); 1549 __ SetAccumulator(result);
1912 __ Dispatch(); 1550 __ Dispatch();
1913 } 1551 }
1914 1552
1553 // Wide
1554 //
1555 // Prefix bytecode indicating next bytecode has wide (16-bit) operands.
1556 void Interpreter::DoWide(InterpreterAssembler* assembler) {
1557 __ RedispatchWide(2);
1558 }
1559
1560 // ExtraWide
1561 //
1562 // Prefix bytecode indicating next bytecode has extra-wide (32-bit) operands.
1563 void Interpreter::DoExtraWide(InterpreterAssembler* assembler) {
1564 __ RedispatchWide(4);
1565 }
1566
1567 // Illegal
1568 //
1569 // An invalid bytecode aborting execution if dispatched.
1570 void Interpreter::DoIllegal(InterpreterAssembler* assembler) {
1571 __ Abort(kInvalidBytecode);
1572 }
1573
1915 } // namespace interpreter 1574 } // namespace interpreter
1916 } // namespace internal 1575 } // namespace internal
1917 } // namespace v8 1576 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698