| 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 |