OLD | NEW |
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/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/interpreter-assembler.h" | 9 #include "src/compiler/interpreter-assembler.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 Node* smi_int = __ SmiTag(raw_int); | 104 Node* smi_int = __ SmiTag(raw_int); |
105 __ SetAccumulator(smi_int); | 105 __ SetAccumulator(smi_int); |
106 __ Dispatch(); | 106 __ Dispatch(); |
107 } | 107 } |
108 | 108 |
109 | 109 |
110 // LdaConstant <idx> | 110 // LdaConstant <idx> |
111 // | 111 // |
112 // Load constant literal at |idx| in the constant pool into the accumulator. | 112 // Load constant literal at |idx| in the constant pool into the accumulator. |
113 void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { | 113 void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { |
114 Node* index = __ BytecodeOperandIdx(0); | 114 Node* index = __ BytecodeOperandIdx8(0); |
115 Node* constant = __ LoadConstantPoolEntry(index); | 115 Node* constant = __ LoadConstantPoolEntry(index); |
116 __ SetAccumulator(constant); | 116 __ SetAccumulator(constant); |
117 __ Dispatch(); | 117 __ Dispatch(); |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 // LdaUndefined | 121 // LdaUndefined |
122 // | 122 // |
123 // Load Undefined into the accumulator. | 123 // Load Undefined into the accumulator. |
124 void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { | 124 void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); | 166 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); |
167 __ SetAccumulator(false_value); | 167 __ SetAccumulator(false_value); |
168 __ Dispatch(); | 168 __ Dispatch(); |
169 } | 169 } |
170 | 170 |
171 | 171 |
172 // Ldar <src> | 172 // Ldar <src> |
173 // | 173 // |
174 // Load accumulator with value from register <src>. | 174 // Load accumulator with value from register <src>. |
175 void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { | 175 void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { |
176 Node* reg_index = __ BytecodeOperandReg(0); | 176 Node* reg_index = __ BytecodeOperandReg8(0); |
177 Node* value = __ LoadRegister(reg_index); | 177 Node* value = __ LoadRegister(reg_index); |
178 __ SetAccumulator(value); | 178 __ SetAccumulator(value); |
179 __ Dispatch(); | 179 __ Dispatch(); |
180 } | 180 } |
181 | 181 |
182 | 182 |
183 // Star <dst> | 183 // Star <dst> |
184 // | 184 // |
185 // Store accumulator to register <dst>. | 185 // Store accumulator to register <dst>. |
186 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { | 186 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { |
187 Node* reg_index = __ BytecodeOperandReg(0); | 187 Node* reg_index = __ BytecodeOperandReg8(0); |
188 Node* accumulator = __ GetAccumulator(); | 188 Node* accumulator = __ GetAccumulator(); |
189 __ StoreRegister(accumulator, reg_index); | 189 __ StoreRegister(accumulator, reg_index); |
190 __ Dispatch(); | 190 __ Dispatch(); |
191 } | 191 } |
192 | 192 |
193 | 193 |
194 // LdaGlobal <slot_index> | 194 // LdaGlobal <slot_index> |
195 // | 195 // |
196 // Load the global at |slot_index| into the accumulator. | 196 // Load the global at |slot_index| into the accumulator. |
197 void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) { | 197 void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) { |
198 Node* slot_index = __ BytecodeOperandIdx(0); | 198 Node* slot_index = __ BytecodeOperandIdx8(0); |
199 Node* smi_slot_index = __ SmiTag(slot_index); | 199 Node* smi_slot_index = __ SmiTag(slot_index); |
200 Node* result = __ CallRuntime(Runtime::kLoadGlobalViaContext, smi_slot_index); | 200 Node* result = __ CallRuntime(Runtime::kLoadGlobalViaContext, smi_slot_index); |
201 __ SetAccumulator(result); | 201 __ SetAccumulator(result); |
202 __ Dispatch(); | 202 __ Dispatch(); |
203 } | 203 } |
204 | 204 |
205 | 205 |
206 void Interpreter::DoPropertyLoadIC(Callable ic, | 206 void Interpreter::DoPropertyLoadIC(Callable ic, |
207 compiler::InterpreterAssembler* assembler) { | 207 compiler::InterpreterAssembler* assembler) { |
208 Node* code_target = __ HeapConstant(ic.code()); | 208 Node* code_target = __ HeapConstant(ic.code()); |
209 Node* reg_index = __ BytecodeOperandReg(0); | 209 Node* reg_index = __ BytecodeOperandReg8(0); |
210 Node* object = __ LoadRegister(reg_index); | 210 Node* object = __ LoadRegister(reg_index); |
211 Node* name = __ GetAccumulator(); | 211 Node* name = __ GetAccumulator(); |
212 Node* raw_slot = __ BytecodeOperandIdx(1); | 212 Node* raw_slot = __ BytecodeOperandIdx8(1); |
213 Node* smi_slot = __ SmiTag(raw_slot); | 213 Node* smi_slot = __ SmiTag(raw_slot); |
214 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 214 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
215 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, | 215 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, |
216 type_feedback_vector); | 216 type_feedback_vector); |
217 __ SetAccumulator(result); | 217 __ SetAccumulator(result); |
218 __ Dispatch(); | 218 __ Dispatch(); |
219 } | 219 } |
220 | 220 |
221 | 221 |
222 // LoadIC <object> <slot> | 222 // LoadIC <object> <slot> |
(...skipping 14 matching lines...) Expand all Loading... |
237 void Interpreter::DoKeyedLoadIC(compiler::InterpreterAssembler* assembler) { | 237 void Interpreter::DoKeyedLoadIC(compiler::InterpreterAssembler* assembler) { |
238 Callable ic = | 238 Callable ic = |
239 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 239 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
240 DoPropertyLoadIC(ic, assembler); | 240 DoPropertyLoadIC(ic, assembler); |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 void Interpreter::DoPropertyStoreIC(Callable ic, | 244 void Interpreter::DoPropertyStoreIC(Callable ic, |
245 compiler::InterpreterAssembler* assembler) { | 245 compiler::InterpreterAssembler* assembler) { |
246 Node* code_target = __ HeapConstant(ic.code()); | 246 Node* code_target = __ HeapConstant(ic.code()); |
247 Node* object_reg_index = __ BytecodeOperandReg(0); | 247 Node* object_reg_index = __ BytecodeOperandReg8(0); |
248 Node* object = __ LoadRegister(object_reg_index); | 248 Node* object = __ LoadRegister(object_reg_index); |
249 Node* name_reg_index = __ BytecodeOperandReg(1); | 249 Node* name_reg_index = __ BytecodeOperandReg8(1); |
250 Node* name = __ LoadRegister(name_reg_index); | 250 Node* name = __ LoadRegister(name_reg_index); |
251 Node* value = __ GetAccumulator(); | 251 Node* value = __ GetAccumulator(); |
252 Node* raw_slot = __ BytecodeOperandIdx(2); | 252 Node* raw_slot = __ BytecodeOperandIdx8(2); |
253 Node* smi_slot = __ SmiTag(raw_slot); | 253 Node* smi_slot = __ SmiTag(raw_slot); |
254 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 254 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
255 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, value, | 255 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, value, |
256 smi_slot, type_feedback_vector); | 256 smi_slot, type_feedback_vector); |
257 __ SetAccumulator(result); | 257 __ SetAccumulator(result); |
258 __ Dispatch(); | 258 __ Dispatch(); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 // StoreIC <object> <name> <slot> | 262 // StoreIC <object> <name> <slot> |
(...skipping 15 matching lines...) Expand all Loading... |
278 Callable ic = | 278 Callable ic = |
279 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 279 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
280 DoPropertyStoreIC(ic, assembler); | 280 DoPropertyStoreIC(ic, assembler); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, | 284 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, |
285 compiler::InterpreterAssembler* assembler) { | 285 compiler::InterpreterAssembler* assembler) { |
286 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized | 286 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized |
287 // operations, instead of calling builtins directly. | 287 // operations, instead of calling builtins directly. |
288 Node* reg_index = __ BytecodeOperandReg(0); | 288 Node* reg_index = __ BytecodeOperandReg8(0); |
289 Node* lhs = __ LoadRegister(reg_index); | 289 Node* lhs = __ LoadRegister(reg_index); |
290 Node* rhs = __ GetAccumulator(); | 290 Node* rhs = __ GetAccumulator(); |
291 Node* result = __ CallRuntime(function_id, lhs, rhs); | 291 Node* result = __ CallRuntime(function_id, lhs, rhs); |
292 __ SetAccumulator(result); | 292 __ SetAccumulator(result); |
293 __ Dispatch(); | 293 __ Dispatch(); |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 // Add <src> | 297 // Add <src> |
298 // | 298 // |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { | 332 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { |
333 DoBinaryOp(Runtime::kModulus, assembler); | 333 DoBinaryOp(Runtime::kModulus, assembler); |
334 } | 334 } |
335 | 335 |
336 | 336 |
337 // Call <receiver> <arg_count> | 337 // Call <receiver> <arg_count> |
338 // | 338 // |
339 // Call a JS function with receiver and |arg_count| arguments in subsequent | 339 // Call a JS function with receiver and |arg_count| arguments in subsequent |
340 // registers. The JSfunction or Callable to call is in the accumulator. | 340 // registers. The JSfunction or Callable to call is in the accumulator. |
341 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { | 341 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { |
342 Node* function_reg = __ BytecodeOperandReg(0); | 342 Node* function_reg = __ BytecodeOperandReg8(0); |
343 Node* function = __ LoadRegister(function_reg); | 343 Node* function = __ LoadRegister(function_reg); |
344 Node* receiver_reg = __ BytecodeOperandReg(1); | 344 Node* receiver_reg = __ BytecodeOperandReg8(1); |
345 Node* first_arg = __ RegisterLocation(receiver_reg); | 345 Node* first_arg = __ RegisterLocation(receiver_reg); |
346 Node* args_count = __ BytecodeOperandCount(2); | 346 Node* args_count = __ BytecodeOperandCount8(2); |
347 Node* result = __ CallJS(function, first_arg, args_count); | 347 Node* result = __ CallJS(function, first_arg, args_count); |
348 __ SetAccumulator(result); | 348 __ SetAccumulator(result); |
349 __ Dispatch(); | 349 __ Dispatch(); |
350 } | 350 } |
351 | 351 |
352 | 352 |
353 // TestEqual <src> | 353 // TestEqual <src> |
354 // | 354 // |
355 // Test if the value in the <src> register equals the accumulator. | 355 // Test if the value in the <src> register equals the accumulator. |
356 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { | 356 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { | 454 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { |
455 Node* relative_jump = __ BytecodeOperandImm8(0); | 455 Node* relative_jump = __ BytecodeOperandImm8(0); |
456 __ Jump(relative_jump); | 456 __ Jump(relative_jump); |
457 } | 457 } |
458 | 458 |
459 | 459 |
460 // JumpConstant <idx> | 460 // JumpConstant <idx> |
461 // | 461 // |
462 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. | 462 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. |
463 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { | 463 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { |
464 Node* index = __ BytecodeOperandIdx(0); | 464 Node* index = __ BytecodeOperandIdx8(0); |
465 Node* constant = __ LoadConstantPoolEntry(index); | 465 Node* constant = __ LoadConstantPoolEntry(index); |
466 Node* relative_jump = __ SmiUntag(constant); | 466 Node* relative_jump = __ SmiUntag(constant); |
467 __ Jump(relative_jump); | 467 __ Jump(relative_jump); |
468 } | 468 } |
469 | 469 |
470 | 470 |
471 // JumpIfTrue <imm8> | 471 // JumpIfTrue <imm8> |
472 // | 472 // |
473 // Jump by number of bytes represented by an immediate operand if the | 473 // Jump by number of bytes represented by an immediate operand if the |
474 // accumulator contains true. | 474 // accumulator contains true. |
475 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { | 475 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { |
476 Node* accumulator = __ GetAccumulator(); | 476 Node* accumulator = __ GetAccumulator(); |
477 Node* relative_jump = __ BytecodeOperandImm8(0); | 477 Node* relative_jump = __ BytecodeOperandImm8(0); |
478 Node* true_value = __ BooleanConstant(true); | 478 Node* true_value = __ BooleanConstant(true); |
479 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 479 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
480 } | 480 } |
481 | 481 |
482 | 482 |
483 // JumpIfTrueConstant <idx> | 483 // JumpIfTrueConstant <idx> |
484 // | 484 // |
485 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 485 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
486 // if the accumulator contains true. | 486 // if the accumulator contains true. |
487 void Interpreter::DoJumpIfTrueConstant( | 487 void Interpreter::DoJumpIfTrueConstant( |
488 compiler::InterpreterAssembler* assembler) { | 488 compiler::InterpreterAssembler* assembler) { |
489 Node* accumulator = __ GetAccumulator(); | 489 Node* accumulator = __ GetAccumulator(); |
490 Node* index = __ BytecodeOperandIdx(0); | 490 Node* index = __ BytecodeOperandIdx8(0); |
491 Node* constant = __ LoadConstantPoolEntry(index); | 491 Node* constant = __ LoadConstantPoolEntry(index); |
492 Node* relative_jump = __ SmiUntag(constant); | 492 Node* relative_jump = __ SmiUntag(constant); |
493 Node* true_value = __ BooleanConstant(true); | 493 Node* true_value = __ BooleanConstant(true); |
494 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 494 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
495 } | 495 } |
496 | 496 |
497 | 497 |
498 // JumpIfFalse <imm8> | 498 // JumpIfFalse <imm8> |
499 // | 499 // |
500 // Jump by number of bytes represented by an immediate operand if the | 500 // Jump by number of bytes represented by an immediate operand if the |
501 // accumulator contains false. | 501 // accumulator contains false. |
502 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { | 502 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { |
503 Node* accumulator = __ GetAccumulator(); | 503 Node* accumulator = __ GetAccumulator(); |
504 Node* relative_jump = __ BytecodeOperandImm8(0); | 504 Node* relative_jump = __ BytecodeOperandImm8(0); |
505 Node* false_value = __ BooleanConstant(false); | 505 Node* false_value = __ BooleanConstant(false); |
506 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 506 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
507 } | 507 } |
508 | 508 |
509 | 509 |
510 // JumpIfFalseConstant <idx> | 510 // JumpIfFalseConstant <idx> |
511 // | 511 // |
512 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 512 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
513 // if the accumulator contains false. | 513 // if the accumulator contains false. |
514 void Interpreter::DoJumpIfFalseConstant( | 514 void Interpreter::DoJumpIfFalseConstant( |
515 compiler::InterpreterAssembler* assembler) { | 515 compiler::InterpreterAssembler* assembler) { |
516 Node* accumulator = __ GetAccumulator(); | 516 Node* accumulator = __ GetAccumulator(); |
517 Node* index = __ BytecodeOperandIdx(0); | 517 Node* index = __ BytecodeOperandIdx8(0); |
518 Node* constant = __ LoadConstantPoolEntry(index); | 518 Node* constant = __ LoadConstantPoolEntry(index); |
519 Node* relative_jump = __ SmiUntag(constant); | 519 Node* relative_jump = __ SmiUntag(constant); |
520 Node* false_value = __ BooleanConstant(false); | 520 Node* false_value = __ BooleanConstant(false); |
521 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 521 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
522 } | 522 } |
523 | 523 |
524 | 524 |
525 // Return | 525 // Return |
526 // | 526 // |
527 // Return the value in register 0. | 527 // Return the value in register 0. |
528 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { | 528 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { |
529 __ Return(); | 529 __ Return(); |
530 } | 530 } |
531 | 531 |
532 | 532 |
533 } // namespace interpreter | 533 } // namespace interpreter |
534 } // namespace internal | 534 } // namespace internal |
535 } // namespace v8 | 535 } // namespace v8 |
OLD | NEW |