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 void Interpreter::DoCompareOp(Token::Value op, | 297 void Interpreter::DoCompareOp(Token::Value op, |
298 compiler::InterpreterAssembler* assembler) { | 298 compiler::InterpreterAssembler* assembler) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { | 341 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { |
342 DoBinaryOp(Runtime::kModulus, assembler); | 342 DoBinaryOp(Runtime::kModulus, assembler); |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 // Call <receiver> <arg_count> | 346 // Call <receiver> <arg_count> |
347 // | 347 // |
348 // Call a JS function with receiver and |arg_count| arguments in subsequent | 348 // Call a JS function with receiver and |arg_count| arguments in subsequent |
349 // registers. The JSfunction or Callable to call is in the accumulator. | 349 // registers. The JSfunction or Callable to call is in the accumulator. |
350 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { | 350 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { |
351 Node* function_reg = __ BytecodeOperandReg(0); | 351 Node* function_reg = __ BytecodeOperandReg8(0); |
352 Node* function = __ LoadRegister(function_reg); | 352 Node* function = __ LoadRegister(function_reg); |
353 Node* receiver_reg = __ BytecodeOperandReg(1); | 353 Node* receiver_reg = __ BytecodeOperandReg8(1); |
354 Node* first_arg = __ RegisterLocation(receiver_reg); | 354 Node* first_arg = __ RegisterLocation(receiver_reg); |
355 Node* args_count = __ BytecodeOperandCount(2); | 355 Node* args_count = __ BytecodeOperandCount8(2); |
356 Node* result = __ CallJS(function, first_arg, args_count); | 356 Node* result = __ CallJS(function, first_arg, args_count); |
357 __ SetAccumulator(result); | 357 __ SetAccumulator(result); |
358 __ Dispatch(); | 358 __ Dispatch(); |
359 } | 359 } |
360 | 360 |
361 | 361 |
362 // TestEqual <src> | 362 // TestEqual <src> |
363 // | 363 // |
364 // Test if the value in the <src> register equals the accumulator. | 364 // Test if the value in the <src> register equals the accumulator. |
365 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { | 365 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { | 463 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { |
464 Node* relative_jump = __ BytecodeOperandImm8(0); | 464 Node* relative_jump = __ BytecodeOperandImm8(0); |
465 __ Jump(relative_jump); | 465 __ Jump(relative_jump); |
466 } | 466 } |
467 | 467 |
468 | 468 |
469 // JumpConstant <idx> | 469 // JumpConstant <idx> |
470 // | 470 // |
471 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. | 471 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. |
472 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { | 472 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { |
473 Node* index = __ BytecodeOperandIdx(0); | 473 Node* index = __ BytecodeOperandIdx8(0); |
474 Node* constant = __ LoadConstantPoolEntry(index); | 474 Node* constant = __ LoadConstantPoolEntry(index); |
475 Node* relative_jump = __ SmiUntag(constant); | 475 Node* relative_jump = __ SmiUntag(constant); |
476 __ Jump(relative_jump); | 476 __ Jump(relative_jump); |
477 } | 477 } |
478 | 478 |
479 | 479 |
480 // JumpIfTrue <imm8> | 480 // JumpIfTrue <imm8> |
481 // | 481 // |
482 // Jump by number of bytes represented by an immediate operand if the | 482 // Jump by number of bytes represented by an immediate operand if the |
483 // accumulator contains true. | 483 // accumulator contains true. |
484 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { | 484 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { |
485 Node* accumulator = __ GetAccumulator(); | 485 Node* accumulator = __ GetAccumulator(); |
486 Node* relative_jump = __ BytecodeOperandImm8(0); | 486 Node* relative_jump = __ BytecodeOperandImm8(0); |
487 Node* true_value = __ BooleanConstant(true); | 487 Node* true_value = __ BooleanConstant(true); |
488 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 488 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
489 } | 489 } |
490 | 490 |
491 | 491 |
492 // JumpIfTrueConstant <idx> | 492 // JumpIfTrueConstant <idx> |
493 // | 493 // |
494 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 494 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
495 // if the accumulator contains true. | 495 // if the accumulator contains true. |
496 void Interpreter::DoJumpIfTrueConstant( | 496 void Interpreter::DoJumpIfTrueConstant( |
497 compiler::InterpreterAssembler* assembler) { | 497 compiler::InterpreterAssembler* assembler) { |
498 Node* accumulator = __ GetAccumulator(); | 498 Node* accumulator = __ GetAccumulator(); |
499 Node* index = __ BytecodeOperandIdx(0); | 499 Node* index = __ BytecodeOperandIdx8(0); |
500 Node* constant = __ LoadConstantPoolEntry(index); | 500 Node* constant = __ LoadConstantPoolEntry(index); |
501 Node* relative_jump = __ SmiUntag(constant); | 501 Node* relative_jump = __ SmiUntag(constant); |
502 Node* true_value = __ BooleanConstant(true); | 502 Node* true_value = __ BooleanConstant(true); |
503 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 503 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
504 } | 504 } |
505 | 505 |
506 | 506 |
507 // JumpIfFalse <imm8> | 507 // JumpIfFalse <imm8> |
508 // | 508 // |
509 // Jump by number of bytes represented by an immediate operand if the | 509 // Jump by number of bytes represented by an immediate operand if the |
510 // accumulator contains false. | 510 // accumulator contains false. |
511 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { | 511 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { |
512 Node* accumulator = __ GetAccumulator(); | 512 Node* accumulator = __ GetAccumulator(); |
513 Node* relative_jump = __ BytecodeOperandImm8(0); | 513 Node* relative_jump = __ BytecodeOperandImm8(0); |
514 Node* false_value = __ BooleanConstant(false); | 514 Node* false_value = __ BooleanConstant(false); |
515 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 515 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
516 } | 516 } |
517 | 517 |
518 | 518 |
519 // JumpIfFalseConstant <idx> | 519 // JumpIfFalseConstant <idx> |
520 // | 520 // |
521 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 521 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
522 // if the accumulator contains false. | 522 // if the accumulator contains false. |
523 void Interpreter::DoJumpIfFalseConstant( | 523 void Interpreter::DoJumpIfFalseConstant( |
524 compiler::InterpreterAssembler* assembler) { | 524 compiler::InterpreterAssembler* assembler) { |
525 Node* accumulator = __ GetAccumulator(); | 525 Node* accumulator = __ GetAccumulator(); |
526 Node* index = __ BytecodeOperandIdx(0); | 526 Node* index = __ BytecodeOperandIdx8(0); |
527 Node* constant = __ LoadConstantPoolEntry(index); | 527 Node* constant = __ LoadConstantPoolEntry(index); |
528 Node* relative_jump = __ SmiUntag(constant); | 528 Node* relative_jump = __ SmiUntag(constant); |
529 Node* false_value = __ BooleanConstant(false); | 529 Node* false_value = __ BooleanConstant(false); |
530 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 530 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
531 } | 531 } |
532 | 532 |
533 | 533 |
534 // Return | 534 // Return |
535 // | 535 // |
536 // Return the value in register 0. | 536 // Return the value in register 0. |
537 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { | 537 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { |
538 __ Return(); | 538 __ Return(); |
539 } | 539 } |
540 | 540 |
541 | 541 |
542 } // namespace interpreter | 542 } // namespace interpreter |
543 } // namespace internal | 543 } // namespace internal |
544 } // namespace v8 | 544 } // namespace v8 |
OLD | NEW |