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/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/compiler/interpreter-assembler.h" | 10 #include "src/compiler/interpreter-assembler.h" |
11 #include "src/factory.h" | 11 #include "src/factory.h" |
12 #include "src/interpreter/bytecode-generator.h" | 12 #include "src/interpreter/bytecode-generator.h" |
13 #include "src/interpreter/bytecodes.h" | 13 #include "src/interpreter/bytecodes.h" |
14 #include "src/zone.h" | 14 #include "src/zone.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace interpreter { | 18 namespace interpreter { |
19 | 19 |
20 using compiler::Node; | 20 using compiler::Node; |
21 | 21 |
22 #define __ assembler-> | 22 #define __ assembler-> |
23 | 23 |
24 | 24 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { |
25 Interpreter::Interpreter(Isolate* isolate) | 25 memset(&dispatch_table_, 0, sizeof(dispatch_table_)); |
26 : isolate_(isolate) {} | |
27 | |
28 | |
29 // static | |
30 Handle<FixedArray> Interpreter::CreateUninitializedInterpreterTable( | |
31 Isolate* isolate) { | |
32 Handle<FixedArray> handler_table = isolate->factory()->NewFixedArray( | |
33 static_cast<int>(Bytecode::kLast) + 1, TENURED); | |
34 // We rely on the interpreter handler table being immovable, so check that | |
35 // it was allocated on the first page (which is always immovable). | |
36 DCHECK(isolate->heap()->old_space()->FirstPage()->Contains( | |
37 handler_table->address())); | |
38 return handler_table; | |
39 } | 26 } |
40 | 27 |
41 | 28 |
42 void Interpreter::Initialize() { | 29 void Interpreter::Initialize() { |
43 DCHECK(FLAG_ignition); | 30 DCHECK(FLAG_ignition); |
44 Handle<FixedArray> handler_table = isolate_->factory()->interpreter_table(); | 31 if (IsDispatchTableInitialized()) return; |
45 if (!IsInterpreterTableInitialized(handler_table)) { | 32 Zone zone; |
46 Zone zone; | 33 HandleScope scope(isolate_); |
47 HandleScope scope(isolate_); | |
48 | 34 |
49 #define GENERATE_CODE(Name, ...) \ | 35 #define GENERATE_CODE(Name, ...) \ |
50 { \ | 36 { \ |
51 compiler::InterpreterAssembler assembler(isolate_, &zone, \ | 37 compiler::InterpreterAssembler assembler(isolate_, &zone, \ |
52 Bytecode::k##Name); \ | 38 Bytecode::k##Name); \ |
53 Do##Name(&assembler); \ | 39 Do##Name(&assembler); \ |
54 Handle<Code> code = assembler.GenerateCode(); \ | 40 Handle<Code> code = assembler.GenerateCode(); \ |
55 handler_table->set(static_cast<int>(Bytecode::k##Name), *code); \ | 41 int index = static_cast<int>(Bytecode::k##Name); \ |
56 } | 42 dispatch_table_[index] = *code; \ |
57 BYTECODE_LIST(GENERATE_CODE) | 43 } |
| 44 BYTECODE_LIST(GENERATE_CODE) |
58 #undef GENERATE_CODE | 45 #undef GENERATE_CODE |
59 } | 46 } |
| 47 |
| 48 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { |
| 49 v->VisitPointers(&dispatch_table_[0], |
| 50 &dispatch_table_[0] + kDispatchTableSize); |
60 } | 51 } |
61 | 52 |
62 | 53 |
63 bool Interpreter::MakeBytecode(CompilationInfo* info) { | 54 bool Interpreter::MakeBytecode(CompilationInfo* info) { |
64 if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) { | 55 if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) { |
65 OFStream os(stdout); | 56 OFStream os(stdout); |
66 base::SmartArrayPointer<char> name = info->GetDebugName(); | 57 base::SmartArrayPointer<char> name = info->GetDebugName(); |
67 os << "[generating bytecode for function: " << info->GetDebugName().get() | 58 os << "[generating bytecode for function: " << info->GetDebugName().get() |
68 << "]" << std::endl | 59 << "]" << std::endl |
69 << std::flush; | 60 << std::flush; |
(...skipping 23 matching lines...) Expand all Loading... |
93 OFStream os(stdout); | 84 OFStream os(stdout); |
94 bytecodes->Print(os); | 85 bytecodes->Print(os); |
95 os << std::flush; | 86 os << std::flush; |
96 } | 87 } |
97 | 88 |
98 info->SetBytecodeArray(bytecodes); | 89 info->SetBytecodeArray(bytecodes); |
99 info->SetCode(info->isolate()->builtins()->InterpreterEntryTrampoline()); | 90 info->SetCode(info->isolate()->builtins()->InterpreterEntryTrampoline()); |
100 return true; | 91 return true; |
101 } | 92 } |
102 | 93 |
103 | 94 bool Interpreter::IsDispatchTableInitialized() { |
104 bool Interpreter::IsInterpreterTableInitialized( | |
105 Handle<FixedArray> handler_table) { | |
106 if (FLAG_trace_ignition) { | 95 if (FLAG_trace_ignition) { |
107 // Regenerate table to add bytecode tracing operations. | 96 // Regenerate table to add bytecode tracing operations. |
108 return false; | 97 return false; |
109 } | 98 } |
110 DCHECK(handler_table->length() == static_cast<int>(Bytecode::kLast) + 1); | 99 return dispatch_table_[0] != nullptr; |
111 return handler_table->get(0) != isolate_->heap()->undefined_value(); | |
112 } | 100 } |
113 | 101 |
114 // LdaZero | 102 // LdaZero |
115 // | 103 // |
116 // Load literal '0' into the accumulator. | 104 // Load literal '0' into the accumulator. |
117 void Interpreter::DoLdaZero(compiler::InterpreterAssembler* assembler) { | 105 void Interpreter::DoLdaZero(compiler::InterpreterAssembler* assembler) { |
118 Node* zero_value = __ NumberConstant(0.0); | 106 Node* zero_value = __ NumberConstant(0.0); |
119 __ SetAccumulator(zero_value); | 107 __ SetAccumulator(zero_value); |
120 __ Dispatch(); | 108 __ Dispatch(); |
121 } | 109 } |
(...skipping 1806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 Node* index_reg = __ BytecodeOperandReg(0); | 1916 Node* index_reg = __ BytecodeOperandReg(0); |
1929 Node* index = __ LoadRegister(index_reg); | 1917 Node* index = __ LoadRegister(index_reg); |
1930 Node* result = __ CallRuntime(Runtime::kForInStep, index); | 1918 Node* result = __ CallRuntime(Runtime::kForInStep, index); |
1931 __ SetAccumulator(result); | 1919 __ SetAccumulator(result); |
1932 __ Dispatch(); | 1920 __ Dispatch(); |
1933 } | 1921 } |
1934 | 1922 |
1935 } // namespace interpreter | 1923 } // namespace interpreter |
1936 } // namespace internal | 1924 } // namespace internal |
1937 } // namespace v8 | 1925 } // namespace v8 |
OLD | NEW |