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