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" |
(...skipping 18 matching lines...) Expand all Loading... |
29 memset(dispatch_table_, 0, sizeof(dispatch_table_)); | 29 memset(dispatch_table_, 0, sizeof(dispatch_table_)); |
30 } | 30 } |
31 | 31 |
32 void Interpreter::Initialize() { | 32 void Interpreter::Initialize() { |
33 if (IsDispatchTableInitialized()) return; | 33 if (IsDispatchTableInitialized()) return; |
34 Zone zone(isolate_->allocator()); | 34 Zone zone(isolate_->allocator()); |
35 HandleScope scope(isolate_); | 35 HandleScope scope(isolate_); |
36 | 36 |
37 if (FLAG_trace_ignition_dispatches) { | 37 if (FLAG_trace_ignition_dispatches) { |
38 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; | 38 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; |
39 bytecode_dispatch_count_table_.Reset( | 39 bytecode_dispatch_counters_table_.Reset( |
40 new uintptr_t[kBytecodeCount * kBytecodeCount]); | 40 new uintptr_t[kBytecodeCount * kBytecodeCount]); |
41 memset(bytecode_dispatch_count_table_.get(), 0, | 41 memset(bytecode_dispatch_counters_table_.get(), 0, |
42 sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount); | 42 sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount); |
43 } | 43 } |
44 | 44 |
45 // Generate bytecode handlers for all bytecodes and scales. | 45 // Generate bytecode handlers for all bytecodes and scales. |
46 for (OperandScale operand_scale = OperandScale::kSingle; | 46 for (OperandScale operand_scale = OperandScale::kSingle; |
47 operand_scale <= OperandScale::kMaxValid; | 47 operand_scale <= OperandScale::kMaxValid; |
48 operand_scale = Bytecodes::NextOperandScale(operand_scale)) { | 48 operand_scale = Bytecodes::NextOperandScale(operand_scale)) { |
49 #define GENERATE_CODE(Name, ...) \ | 49 #define GENERATE_CODE(Name, ...) \ |
50 { \ | 50 { \ |
51 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ | 51 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 if (dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] == \ | 192 if (dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] == \ |
193 code->entry()) { \ | 193 code->entry()) { \ |
194 return #Name; \ | 194 return #Name; \ |
195 } | 195 } |
196 BYTECODE_LIST(RETURN_NAME) | 196 BYTECODE_LIST(RETURN_NAME) |
197 #undef RETURN_NAME | 197 #undef RETURN_NAME |
198 #endif // ENABLE_DISASSEMBLER | 198 #endif // ENABLE_DISASSEMBLER |
199 return nullptr; | 199 return nullptr; |
200 } | 200 } |
201 | 201 |
202 void Interpreter::WriteDispatchCounters() { | 202 uintptr_t Interpreter::GetDispatchCounter(Bytecode from, Bytecode to) const { |
203 std::ofstream stream(FLAG_trace_ignition_dispatches_output_file); | 203 int from_index = Bytecodes::ToByte(from); |
204 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; | 204 int to_index = Bytecodes::ToByte(to); |
| 205 return bytecode_dispatch_counters_table_[from_index * kNumberOfBytecodes + |
| 206 to_index]; |
| 207 } |
| 208 |
| 209 Local<v8::Object> Interpreter::GetDispatchCountersObject() { |
| 210 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(isolate_); |
| 211 Local<v8::Context> context = isolate->GetCurrentContext(); |
| 212 |
| 213 Local<v8::Object> counters_map = v8::Object::New(isolate); |
205 | 214 |
206 // Output is a JSON-encoded object of objects. | 215 // Output is a JSON-encoded object of objects. |
207 // | 216 // |
208 // The keys on the top level object are source bytecodes, | 217 // The keys on the top level object are source bytecodes, |
209 // and corresponding value are objects. Keys on these last are the | 218 // and corresponding value are objects. Keys on these last are the |
210 // destinations of the dispatch and the value associated is a counter for | 219 // destinations of the dispatch and the value associated is a counter for |
211 // the correspondent source-destination dispatch chain. | 220 // the correspondent source-destination dispatch chain. |
212 // | 221 // |
213 // Only non-zero counters are written to file, but an entry in the top-level | 222 // Only non-zero counters are written to file, but an entry in the top-level |
214 // object is always present, even if the value is empty because all counters | 223 // object is always present, even if the value is empty because all counters |
215 // for that source are zero. | 224 // for that source are zero. |
216 | 225 |
217 stream << '{'; | 226 for (int from_index = 0; from_index < kNumberOfBytecodes; ++from_index) { |
| 227 Bytecode from_bytecode = Bytecodes::FromByte(from_index); |
| 228 Local<v8::Object> counters_row = v8::Object::New(isolate); |
218 | 229 |
219 for (int from_index = 0; from_index < kBytecodeCount; ++from_index) { | 230 for (int to_index = 0; to_index < kNumberOfBytecodes; ++to_index) { |
220 if (from_index > 0) stream << ",\n "; | 231 Bytecode to_bytecode = Bytecodes::FromByte(to_index); |
| 232 uintptr_t counter = GetDispatchCounter(from_bytecode, to_bytecode); |
221 | 233 |
222 Bytecode from_bytecode = Bytecodes::FromByte(from_index); | |
223 stream << "\"" << Bytecodes::ToString(from_bytecode) << "\": {"; | |
224 | |
225 bool emitted_first = false; | |
226 for (int to_index = 0; to_index < kBytecodeCount; ++to_index) { | |
227 uintptr_t counter = | |
228 bytecode_dispatch_count_table_[from_index * kBytecodeCount + | |
229 to_index]; | |
230 if (counter > 0) { | 234 if (counter > 0) { |
231 if (emitted_first) { | 235 std::string to_name = Bytecodes::ToString(to_bytecode); |
232 stream << ", "; | 236 Local<v8::String> to_name_object = |
233 } else { | 237 v8::String::NewFromUtf8(isolate, to_name.c_str(), |
234 emitted_first = true; | 238 NewStringType::kNormal) |
235 } | 239 .ToLocalChecked(); |
236 | 240 Local<v8::Number> counter_object = v8::Number::New(isolate, counter); |
237 Bytecode to_bytecode = Bytecodes::FromByte(to_index); | 241 CHECK(counters_row->Set(context, to_name_object, counter_object) |
238 stream << '"' << Bytecodes::ToString(to_bytecode) << "\": " << counter; | 242 .IsJust()); |
239 } | 243 } |
240 } | 244 } |
241 | 245 |
242 stream << "}"; | 246 std::string from_name = Bytecodes::ToString(from_bytecode); |
| 247 Local<v8::String> from_name_object = |
| 248 v8::String::NewFromUtf8(isolate, from_name.c_str(), |
| 249 NewStringType::kNormal) |
| 250 .ToLocalChecked(); |
| 251 |
| 252 CHECK(counters_map->Set(context, from_name_object, counters_row).IsJust()); |
243 } | 253 } |
244 | 254 |
245 stream << '}'; | 255 return counters_map; |
246 } | 256 } |
247 | 257 |
248 // LdaZero | 258 // LdaZero |
249 // | 259 // |
250 // Load literal '0' into the accumulator. | 260 // Load literal '0' into the accumulator. |
251 void Interpreter::DoLdaZero(InterpreterAssembler* assembler) { | 261 void Interpreter::DoLdaZero(InterpreterAssembler* assembler) { |
252 Node* zero_value = __ NumberConstant(0.0); | 262 Node* zero_value = __ NumberConstant(0.0); |
253 __ SetAccumulator(zero_value); | 263 __ SetAccumulator(zero_value); |
254 __ Dispatch(); | 264 __ Dispatch(); |
255 } | 265 } |
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 // Illegal | 1691 // Illegal |
1682 // | 1692 // |
1683 // An invalid bytecode aborting execution if dispatched. | 1693 // An invalid bytecode aborting execution if dispatched. |
1684 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { | 1694 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { |
1685 __ Abort(kInvalidBytecode); | 1695 __ Abort(kInvalidBytecode); |
1686 } | 1696 } |
1687 | 1697 |
1688 } // namespace interpreter | 1698 } // namespace interpreter |
1689 } // namespace internal | 1699 } // namespace internal |
1690 } // namespace v8 | 1700 } // namespace v8 |
OLD | NEW |