Chromium Code Reviews| 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 <fstream> | 7 #include <fstream> |
| 8 | 8 |
| 9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| 11 #include "src/compiler.h" | 11 #include "src/compiler.h" |
| 12 #include "src/factory.h" | 12 #include "src/factory.h" |
| 13 #include "src/interpreter/bytecode-generator.h" | 13 #include "src/interpreter/bytecode-generator.h" |
| 14 #include "src/interpreter/bytecodes.h" | 14 #include "src/interpreter/bytecodes.h" |
| 15 #include "src/interpreter/interpreter-assembler.h" | 15 #include "src/interpreter/interpreter-assembler.h" |
| 16 #include "src/interpreter/interpreter-intrinsics.h" | 16 #include "src/interpreter/interpreter-intrinsics.h" |
| 17 #include "src/log.h" | 17 #include "src/log.h" |
| 18 #include "src/zone.h" | 18 #include "src/zone.h" |
| 19 | 19 |
| 20 namespace v8 { | 20 namespace v8 { |
| 21 namespace internal { | 21 namespace internal { |
| 22 namespace interpreter { | 22 namespace interpreter { |
| 23 | 23 |
| 24 using compiler::Node; | 24 using compiler::Node; |
| 25 typedef CodeStubAssembler::Label Label; | 25 typedef CodeStubAssembler::Label Label; |
| 26 typedef CodeStubAssembler::Variable Variable; | 26 typedef CodeStubAssembler::Variable Variable; |
| 27 | 27 |
| 28 #define __ assembler-> | 28 #define __ assembler-> |
| 29 typedef compiler::CodeAssembler::Label Label; | |
| 30 typedef compiler::CodeAssembler::Variable Variable; | |
| 29 | 31 |
| 30 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { | 32 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { |
| 31 memset(dispatch_table_, 0, sizeof(dispatch_table_)); | 33 memset(dispatch_table_, 0, sizeof(dispatch_table_)); |
| 32 } | 34 } |
| 33 | 35 |
| 34 void Interpreter::Initialize() { | 36 void Interpreter::Initialize() { |
| 35 if (IsDispatchTableInitialized()) return; | 37 if (IsDispatchTableInitialized()) return; |
| 36 Zone zone(isolate_->allocator()); | 38 Zone zone(isolate_->allocator()); |
| 37 HandleScope scope(isolate_); | 39 HandleScope scope(isolate_); |
| 38 | 40 |
| (...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 // if the object referenced by the accumulator is the hole constant. | 1390 // if the object referenced by the accumulator is the hole constant. |
| 1389 void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) { | 1391 void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) { |
| 1390 Node* accumulator = __ GetAccumulator(); | 1392 Node* accumulator = __ GetAccumulator(); |
| 1391 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); | 1393 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); |
| 1392 Node* index = __ BytecodeOperandIdx(0); | 1394 Node* index = __ BytecodeOperandIdx(0); |
| 1393 Node* constant = __ LoadConstantPoolEntry(index); | 1395 Node* constant = __ LoadConstantPoolEntry(index); |
| 1394 Node* relative_jump = __ SmiUntag(constant); | 1396 Node* relative_jump = __ SmiUntag(constant); |
| 1395 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump); | 1397 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump); |
| 1396 } | 1398 } |
| 1397 | 1399 |
| 1398 void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, | |
| 1399 InterpreterAssembler* assembler) { | |
| 1400 Node* index = __ BytecodeOperandIdx(0); | |
| 1401 Node* constant_elements = __ LoadConstantPoolEntry(index); | |
| 1402 Node* literal_index_raw = __ BytecodeOperandIdx(1); | |
| 1403 Node* literal_index = __ SmiTag(literal_index_raw); | |
| 1404 Node* flags_raw = __ BytecodeOperandFlag(2); | |
| 1405 Node* flags = __ SmiTag(flags_raw); | |
| 1406 Node* closure = __ LoadRegister(Register::function_closure()); | |
| 1407 Node* context = __ GetContext(); | |
| 1408 Node* result = __ CallRuntime(function_id, context, closure, literal_index, | |
| 1409 constant_elements, flags); | |
| 1410 __ SetAccumulator(result); | |
| 1411 __ Dispatch(); | |
| 1412 } | |
| 1413 | |
| 1414 | |
| 1415 // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags> | 1400 // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags> |
| 1416 // | 1401 // |
| 1417 // Creates a regular expression literal for literal index <literal_idx> with | 1402 // Creates a regular expression literal for literal index <literal_idx> with |
| 1418 // <flags> and the pattern in <pattern_idx>. | 1403 // <flags> and the pattern in <pattern_idx>. |
| 1419 void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) { | 1404 void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) { |
| 1420 Callable callable = CodeFactory::FastCloneRegExp(isolate_); | 1405 Callable callable = CodeFactory::FastCloneRegExp(isolate_); |
| 1421 Node* target = __ HeapConstant(callable.code()); | 1406 Node* target = __ HeapConstant(callable.code()); |
| 1422 Node* index = __ BytecodeOperandIdx(0); | 1407 Node* index = __ BytecodeOperandIdx(0); |
| 1423 Node* pattern = __ LoadConstantPoolEntry(index); | 1408 Node* pattern = __ LoadConstantPoolEntry(index); |
| 1424 Node* literal_index_raw = __ BytecodeOperandIdx(1); | 1409 Node* literal_index_raw = __ BytecodeOperandIdx(1); |
| 1425 Node* literal_index = __ SmiTag(literal_index_raw); | 1410 Node* literal_index = __ SmiTag(literal_index_raw); |
| 1426 Node* flags_raw = __ BytecodeOperandFlag(2); | 1411 Node* flags_raw = __ BytecodeOperandFlag(2); |
| 1427 Node* flags = __ SmiTag(flags_raw); | 1412 Node* flags = __ SmiTag(flags_raw); |
| 1428 Node* closure = __ LoadRegister(Register::function_closure()); | 1413 Node* closure = __ LoadRegister(Register::function_closure()); |
| 1429 Node* context = __ GetContext(); | 1414 Node* context = __ GetContext(); |
| 1430 Node* result = __ CallStub(callable.descriptor(), target, context, closure, | 1415 Node* result = __ CallStub(callable.descriptor(), target, context, closure, |
| 1431 literal_index, pattern, flags); | 1416 literal_index, pattern, flags); |
| 1432 __ SetAccumulator(result); | 1417 __ SetAccumulator(result); |
| 1433 __ Dispatch(); | 1418 __ Dispatch(); |
| 1434 } | 1419 } |
| 1435 | 1420 |
| 1436 // CreateArrayLiteral <element_idx> <literal_idx> <flags> | 1421 // CreateArrayLiteral <element_idx> <literal_idx> <flags> |
| 1437 // | 1422 // |
| 1438 // Creates an array literal for literal index <literal_idx> with flags <flags> | 1423 // Creates an array literal for literal index <literal_idx> with flags <flags> |
| 1439 // and constant elements in <element_idx>. | 1424 // and constant elements in <element_idx>. |
| 1440 void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) { | 1425 void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) { |
| 1441 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler); | 1426 Node* index = __ BytecodeOperandIdx(0); |
| 1427 Node* constant_elements = __ LoadConstantPoolEntry(index); | |
| 1428 Node* literal_index_raw = __ BytecodeOperandIdx(1); | |
| 1429 Node* literal_index = __ SmiTag(literal_index_raw); | |
| 1430 Node* flags_raw = __ BytecodeOperandFlag(2); | |
| 1431 Node* flags = __ SmiTag(flags_raw); | |
| 1432 Node* closure = __ LoadRegister(Register::function_closure()); | |
| 1433 Node* context = __ GetContext(); | |
| 1434 Node* result = __ CallRuntime(Runtime::kCreateArrayLiteral, context, closure, | |
| 1435 literal_index, constant_elements, flags); | |
| 1436 __ SetAccumulator(result); | |
| 1437 __ Dispatch(); | |
| 1442 } | 1438 } |
| 1443 | 1439 |
| 1444 // CreateObjectLiteral <element_idx> <literal_idx> <flags> | 1440 // CreateObjectLiteral <element_idx> <literal_idx> <flags> |
| 1445 // | 1441 // |
| 1446 // Creates an object literal for literal index <literal_idx> with flags <flags> | 1442 // Creates an object literal for literal index <literal_idx> with |
| 1447 // and constant elements in <element_idx>. | 1443 // CreateObjectLiteralFlags <flags> and constant elements in <element_idx>. |
| 1448 void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) { | 1444 void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) { |
| 1449 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler); | 1445 Node* literal_index_raw = __ BytecodeOperandIdx(1); |
| 1446 Node* literal_index = __ SmiTag(literal_index_raw); | |
| 1447 Node* bytecode_flags = __ BytecodeOperandFlag(2); | |
| 1448 Node* closure = __ LoadRegister(Register::function_closure()); | |
| 1449 | |
| 1450 Variable result(assembler, MachineRepresentation::kTagged); | |
| 1451 | |
| 1452 // Check if we can do a fast clone or have to call the runtime. | |
| 1453 Label end(assembler), if_fast_clone(assembler), | |
| 1454 if_not_fast_clone(assembler, Label::kDeferred); | |
| 1455 Node* fast_clone_properties_count = | |
| 1456 __ BitFieldDecode<CreateObjectLiteralFlags::FastClonePropertiesCountBits>( | |
| 1457 bytecode_flags); | |
| 1458 __ BranchIf(fast_clone_properties_count, &if_fast_clone, &if_not_fast_clone); | |
|
Toon Verwaest
2016/04/27 08:50:19
Does this flag change over time? If not, why not h
rmcilroy
2016/04/28 13:30:52
I considered this, but I didn't think it was worth
| |
| 1459 | |
| 1460 __ Bind(&if_fast_clone); | |
| 1461 { | |
| 1462 // If we can do a fast clone, calculate the object size based on the | |
| 1463 // properties count and clone the shallow elements. | |
| 1464 Node* object_size = | |
| 1465 __ WordShl(fast_clone_properties_count, kPointerSizeLog2); | |
|
Toon Verwaest
2016/04/27 08:50:19
What about just passing in fast_clone_properties_c
rmcilroy
2016/04/28 13:30:52
Works for me, done.
| |
| 1466 object_size = | |
| 1467 __ IntPtrAdd(object_size, __ IntPtrConstant(JSObject::kHeaderSize)); | |
| 1468 | |
| 1469 Node* clone = FastCloneShallowObjectStub::GenerateFastPath( | |
| 1470 assembler, &if_not_fast_clone, closure, literal_index, object_size); | |
| 1471 result.Bind(clone); | |
| 1472 __ Goto(&end); | |
| 1473 } | |
| 1474 | |
| 1475 __ Bind(&if_not_fast_clone); | |
| 1476 { | |
| 1477 // If we can't do a fast clone, call into the runtime. | |
| 1478 Node* index = __ BytecodeOperandIdx(0); | |
| 1479 Node* constant_elements = __ LoadConstantPoolEntry(index); | |
| 1480 Node* context = __ GetContext(); | |
| 1481 | |
| 1482 STATIC_ASSERT(CreateObjectLiteralFlags::FlagsBits::kShift == 0); | |
| 1483 Node* flags_raw = __ Word32And( | |
| 1484 bytecode_flags, | |
| 1485 __ Int32Constant(CreateObjectLiteralFlags::FlagsBits::kMask)); | |
| 1486 Node* flags = __ SmiTag(flags_raw); | |
| 1487 | |
| 1488 result.Bind(__ CallRuntime(Runtime::kCreateObjectLiteral, context, closure, | |
| 1489 literal_index, constant_elements, flags)); | |
| 1490 __ Goto(&end); | |
| 1491 } | |
| 1492 | |
| 1493 __ Bind(&end); | |
| 1494 __ SetAccumulator(result.value()); | |
| 1495 __ Dispatch(); | |
| 1450 } | 1496 } |
| 1451 | 1497 |
| 1452 // CreateClosure <index> <tenured> | 1498 // CreateClosure <index> <tenured> |
| 1453 // | 1499 // |
| 1454 // Creates a new closure for SharedFunctionInfo at position |index| in the | 1500 // Creates a new closure for SharedFunctionInfo at position |index| in the |
| 1455 // constant pool and with the PretenureFlag <tenured>. | 1501 // constant pool and with the PretenureFlag <tenured>. |
| 1456 void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) { | 1502 void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) { |
| 1457 // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of | 1503 // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of |
| 1458 // calling into the runtime. | 1504 // calling into the runtime. |
| 1459 Node* index = __ BytecodeOperandIdx(0); | 1505 Node* index = __ BytecodeOperandIdx(0); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1767 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 1813 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
| 1768 __ SmiTag(new_state)); | 1814 __ SmiTag(new_state)); |
| 1769 __ SetAccumulator(old_state); | 1815 __ SetAccumulator(old_state); |
| 1770 | 1816 |
| 1771 __ Dispatch(); | 1817 __ Dispatch(); |
| 1772 } | 1818 } |
| 1773 | 1819 |
| 1774 } // namespace interpreter | 1820 } // namespace interpreter |
| 1775 } // namespace internal | 1821 } // namespace internal |
| 1776 } // namespace v8 | 1822 } // namespace v8 |
| OLD | NEW |