LCOV - code coverage report
Current view: top level - src/runtime - runtime-interpreter.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1 1 100.0 %
Date: 2019-02-19 Functions: 2 2 100.0 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <iomanip>
       6             : 
       7             : #include "src/arguments-inl.h"
       8             : #include "src/counters.h"
       9             : #include "src/frames-inl.h"
      10             : #include "src/interpreter/bytecode-array-iterator.h"
      11             : #include "src/interpreter/bytecode-decoder.h"
      12             : #include "src/interpreter/bytecode-flags.h"
      13             : #include "src/interpreter/bytecode-register.h"
      14             : #include "src/interpreter/bytecodes.h"
      15             : #include "src/interpreter/interpreter.h"
      16             : #include "src/isolate-inl.h"
      17             : #include "src/ostreams.h"
      18             : #include "src/runtime/runtime-utils.h"
      19             : #include "src/snapshot/snapshot.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : #ifdef V8_TRACE_IGNITION
      25             : 
      26             : namespace {
      27             : 
      28             : void AdvanceToOffsetForTracing(
      29             :     interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) {
      30             :   while (bytecode_iterator.current_offset() +
      31             :              bytecode_iterator.current_bytecode_size() <=
      32             :          offset) {
      33             :     bytecode_iterator.Advance();
      34             :   }
      35             :   DCHECK(bytecode_iterator.current_offset() == offset ||
      36             :          ((bytecode_iterator.current_offset() + 1) == offset &&
      37             :           bytecode_iterator.current_operand_scale() >
      38             :               interpreter::OperandScale::kSingle));
      39             : }
      40             : 
      41             : void PrintRegisters(Isolate* isolate, std::ostream& os, bool is_input,
      42             :                     interpreter::BytecodeArrayIterator& bytecode_iterator,
      43             :                     Handle<Object> accumulator) {
      44             :   static const char kAccumulator[] = "accumulator";
      45             :   static const int kRegFieldWidth = static_cast<int>(sizeof(kAccumulator) - 1);
      46             :   static const char* kInputColourCode = "\033[0;36m";
      47             :   static const char* kOutputColourCode = "\033[0;35m";
      48             :   static const char* kNormalColourCode = "\033[0;m";
      49             :   const char* kArrowDirection = is_input ? " -> " : " <- ";
      50             :   if (FLAG_log_colour) {
      51             :     os << (is_input ? kInputColourCode : kOutputColourCode);
      52             :   }
      53             : 
      54             :   interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
      55             : 
      56             :   // Print accumulator.
      57             :   if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
      58             :       (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
      59             :     os << "      [ " << kAccumulator << kArrowDirection;
      60             :     accumulator->ShortPrint();
      61             :     os << " ]" << std::endl;
      62             :   }
      63             : 
      64             :   // Print the registers.
      65             :   JavaScriptFrameIterator frame_iterator(isolate);
      66             :   InterpretedFrame* frame =
      67             :       reinterpret_cast<InterpretedFrame*>(frame_iterator.frame());
      68             :   int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
      69             :   for (int operand_index = 0; operand_index < operand_count; operand_index++) {
      70             :     interpreter::OperandType operand_type =
      71             :         interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
      72             :     bool should_print =
      73             :         is_input
      74             :             ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
      75             :             : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
      76             :     if (should_print) {
      77             :       interpreter::Register first_reg =
      78             :           bytecode_iterator.GetRegisterOperand(operand_index);
      79             :       int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
      80             :       for (int reg_index = first_reg.index();
      81             :            reg_index < first_reg.index() + range; reg_index++) {
      82             :         Object reg_object = frame->ReadInterpreterRegister(reg_index);
      83             :         os << "      [ " << std::setw(kRegFieldWidth)
      84             :            << interpreter::Register(reg_index).ToString(
      85             :                   bytecode_iterator.bytecode_array()->parameter_count())
      86             :            << kArrowDirection;
      87             :         reg_object->ShortPrint(os);
      88             :         os << " ]" << std::endl;
      89             :       }
      90             :     }
      91             :   }
      92             :   if (FLAG_log_colour) {
      93             :     os << kNormalColourCode;
      94             :   }
      95             : }
      96             : 
      97             : }  // namespace
      98             : 
      99             : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
     100             :   if (!FLAG_trace_ignition) {
     101             :     return ReadOnlyRoots(isolate).undefined_value();
     102             :   }
     103             : 
     104             :   SealHandleScope shs(isolate);
     105             :   DCHECK_EQ(3, args.length());
     106             :   CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
     107             :   CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
     108             :   CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
     109             : 
     110             :   int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
     111             :   interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
     112             :   AdvanceToOffsetForTracing(bytecode_iterator, offset);
     113             :   if (offset == bytecode_iterator.current_offset()) {
     114             :     StdoutStream os;
     115             : 
     116             :     // Print bytecode.
     117             :     const uint8_t* base_address = reinterpret_cast<const uint8_t*>(
     118             :         bytecode_array->GetFirstBytecodeAddress());
     119             :     const uint8_t* bytecode_address = base_address + offset;
     120             :     os << " -> " << static_cast<const void*>(bytecode_address) << " @ "
     121             :        << std::setw(4) << offset << " : ";
     122             :     interpreter::BytecodeDecoder::Decode(os, bytecode_address,
     123             :                                          bytecode_array->parameter_count());
     124             :     os << std::endl;
     125             :     // Print all input registers and accumulator.
     126             :     PrintRegisters(isolate, os, true, bytecode_iterator, accumulator);
     127             : 
     128             :     os << std::flush;
     129             :   }
     130             :   return ReadOnlyRoots(isolate).undefined_value();
     131             : }
     132             : 
     133             : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
     134             :   if (!FLAG_trace_ignition) {
     135             :     return ReadOnlyRoots(isolate).undefined_value();
     136             :   }
     137             : 
     138             :   SealHandleScope shs(isolate);
     139             :   DCHECK_EQ(3, args.length());
     140             :   CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
     141             :   CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
     142             :   CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
     143             : 
     144             :   int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
     145             :   interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
     146             :   AdvanceToOffsetForTracing(bytecode_iterator, offset);
     147             :   // The offset comparison here ensures registers only printed when the
     148             :   // (potentially) widened bytecode has completed. The iterator reports
     149             :   // the offset as the offset of the prefix bytecode.
     150             :   if (bytecode_iterator.current_operand_scale() ==
     151             :           interpreter::OperandScale::kSingle ||
     152             :       offset > bytecode_iterator.current_offset()) {
     153             :     StdoutStream os;
     154             :     // Print all output registers and accumulator.
     155             :     PrintRegisters(isolate, os, false, bytecode_iterator, accumulator);
     156             :     os << std::flush;
     157             :   }
     158             :   return ReadOnlyRoots(isolate).undefined_value();
     159             : }
     160             : 
     161             : #endif
     162             : 
     163             : #ifdef V8_TRACE_FEEDBACK_UPDATES
     164             : 
     165             : RUNTIME_FUNCTION(Runtime_InterpreterTraceUpdateFeedback) {
     166             :   if (!FLAG_trace_feedback_updates) {
     167             :     return ReadOnlyRoots(isolate).undefined_value();
     168             :   }
     169             : 
     170             :   SealHandleScope shs(isolate);
     171             :   DCHECK_EQ(3, args.length());
     172             :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     173             :   CONVERT_SMI_ARG_CHECKED(slot, 1);
     174             :   CONVERT_ARG_CHECKED(String, reason, 2);
     175             : 
     176             :   int slot_count = function->feedback_vector()->metadata()->slot_count();
     177             : 
     178             :   StdoutStream os;
     179             :   os << "[Feedback slot " << slot << "/" << slot_count << " in ";
     180             :   function->shared()->ShortPrint(os);
     181             :   os << " updated to ";
     182             :   function->feedback_vector()->FeedbackSlotPrint(os, FeedbackSlot(slot));
     183             :   os << " - ";
     184             : 
     185             :   StringCharacterStream stream(reason);
     186             :   while (stream.HasMore()) {
     187             :     uint16_t character = stream.GetNext();
     188             :     PrintF("%c", character);
     189             :   }
     190             : 
     191             :   os << "]" << std::endl;
     192             : 
     193             :   return ReadOnlyRoots(isolate).undefined_value();
     194             : }
     195             : 
     196             : #endif
     197             : 
     198             : }  // namespace internal
     199      178779 : }  // namespace v8

Generated by: LCOV version 1.10