LCOV - code coverage report
Current view: top level - src/runtime - runtime-interpreter.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 10 10 100.0 %
Date: 2017-10-20 Functions: 1 2 50.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 "src/runtime/runtime-utils.h"
       6             : 
       7             : #include <iomanip>
       8             : 
       9             : #include "src/arguments.h"
      10             : #include "src/frames-inl.h"
      11             : #include "src/interpreter/bytecode-array-iterator.h"
      12             : #include "src/interpreter/bytecode-decoder.h"
      13             : #include "src/interpreter/bytecode-flags.h"
      14             : #include "src/interpreter/bytecode-register.h"
      15             : #include "src/interpreter/bytecodes.h"
      16             : #include "src/isolate-inl.h"
      17             : #include "src/ostreams.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22    20275666 : RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
      23     6758556 :   HandleScope scope(isolate);
      24             :   DCHECK_EQ(4, args.length());
      25    13517112 :   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
      26    13517112 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1);
      27    13517112 :   CONVERT_SMI_ARG_CHECKED(index, 2);
      28    13517110 :   CONVERT_SMI_ARG_CHECKED(pretenured_flag, 3);
      29     6758555 :   Handle<Context> context(isolate->context(), isolate);
      30     6758555 :   FeedbackSlot slot = FeedbackVector::ToSlot(index);
      31     6758555 :   Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate);
      32             :   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
      33             :       shared, context, vector_cell,
      34    13517109 :       static_cast<PretenureFlag>(pretenured_flag));
      35             : }
      36             : 
      37             : #ifdef V8_TRACE_IGNITION
      38             : 
      39             : namespace {
      40             : 
      41             : void AdvanceToOffsetForTracing(
      42             :     interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) {
      43             :   while (bytecode_iterator.current_offset() +
      44             :              bytecode_iterator.current_bytecode_size() <=
      45             :          offset) {
      46             :     bytecode_iterator.Advance();
      47             :   }
      48             :   DCHECK(bytecode_iterator.current_offset() == offset ||
      49             :          ((bytecode_iterator.current_offset() + 1) == offset &&
      50             :           bytecode_iterator.current_operand_scale() >
      51             :               interpreter::OperandScale::kSingle));
      52             : }
      53             : 
      54             : void PrintRegisters(std::ostream& os, bool is_input,
      55             :                     interpreter::BytecodeArrayIterator& bytecode_iterator,
      56             :                     Handle<Object> accumulator) {
      57             :   static const char kAccumulator[] = "accumulator";
      58             :   static const int kRegFieldWidth = static_cast<int>(sizeof(kAccumulator) - 1);
      59             :   static const char* kInputColourCode = "\033[0;36m";
      60             :   static const char* kOutputColourCode = "\033[0;35m";
      61             :   static const char* kNormalColourCode = "\033[0;m";
      62             :   const char* kArrowDirection = is_input ? " -> " : " <- ";
      63             :   if (FLAG_log_colour) {
      64             :     os << (is_input ? kInputColourCode : kOutputColourCode);
      65             :   }
      66             : 
      67             :   interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
      68             : 
      69             :   // Print accumulator.
      70             :   if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
      71             :       (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
      72             :     os << "      [ " << kAccumulator << kArrowDirection;
      73             :     accumulator->ShortPrint();
      74             :     os << " ]" << std::endl;
      75             :   }
      76             : 
      77             :   // Print the registers.
      78             :   JavaScriptFrameIterator frame_iterator(
      79             :       bytecode_iterator.bytecode_array()->GetIsolate());
      80             :   InterpretedFrame* frame =
      81             :       reinterpret_cast<InterpretedFrame*>(frame_iterator.frame());
      82             :   int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
      83             :   for (int operand_index = 0; operand_index < operand_count; operand_index++) {
      84             :     interpreter::OperandType operand_type =
      85             :         interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
      86             :     bool should_print =
      87             :         is_input
      88             :             ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
      89             :             : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
      90             :     if (should_print) {
      91             :       interpreter::Register first_reg =
      92             :           bytecode_iterator.GetRegisterOperand(operand_index);
      93             :       int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
      94             :       for (int reg_index = first_reg.index();
      95             :            reg_index < first_reg.index() + range; reg_index++) {
      96             :         Object* reg_object = frame->ReadInterpreterRegister(reg_index);
      97             :         os << "      [ " << std::setw(kRegFieldWidth)
      98             :            << interpreter::Register(reg_index).ToString(
      99             :                   bytecode_iterator.bytecode_array()->parameter_count())
     100             :            << kArrowDirection;
     101             :         reg_object->ShortPrint(os);
     102             :         os << " ]" << std::endl;
     103             :       }
     104             :     }
     105             :   }
     106             :   if (FLAG_log_colour) {
     107             :     os << kNormalColourCode;
     108             :   }
     109             : }
     110             : 
     111             : }  // namespace
     112             : 
     113             : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
     114             :   if (!FLAG_trace_ignition) {
     115             :     return isolate->heap()->undefined_value();
     116             :   }
     117             : 
     118             :   SealHandleScope shs(isolate);
     119             :   DCHECK_EQ(3, args.length());
     120             :   CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
     121             :   CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
     122             :   CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
     123             : 
     124             :   int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
     125             :   interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
     126             :   AdvanceToOffsetForTracing(bytecode_iterator, offset);
     127             :   if (offset == bytecode_iterator.current_offset()) {
     128             :     OFStream os(stdout);
     129             : 
     130             :     // Print bytecode.
     131             :     const uint8_t* base_address = bytecode_array->GetFirstBytecodeAddress();
     132             :     const uint8_t* bytecode_address = base_address + offset;
     133             :     os << " -> " << static_cast<const void*>(bytecode_address) << " @ "
     134             :        << std::setw(4) << offset << " : ";
     135             :     interpreter::BytecodeDecoder::Decode(os, bytecode_address,
     136             :                                          bytecode_array->parameter_count());
     137             :     os << std::endl;
     138             :     // Print all input registers and accumulator.
     139             :     PrintRegisters(os, true, bytecode_iterator, accumulator);
     140             : 
     141             :     os << std::flush;
     142             :   }
     143             :   return isolate->heap()->undefined_value();
     144             : }
     145             : 
     146             : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
     147             :   if (!FLAG_trace_ignition) {
     148             :     return isolate->heap()->undefined_value();
     149             :   }
     150             : 
     151             :   SealHandleScope shs(isolate);
     152             :   DCHECK_EQ(3, args.length());
     153             :   CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
     154             :   CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
     155             :   CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
     156             : 
     157             :   int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
     158             :   interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
     159             :   AdvanceToOffsetForTracing(bytecode_iterator, offset);
     160             :   // The offset comparison here ensures registers only printed when the
     161             :   // (potentially) widened bytecode has completed. The iterator reports
     162             :   // the offset as the offset of the prefix bytecode.
     163             :   if (bytecode_iterator.current_operand_scale() ==
     164             :           interpreter::OperandScale::kSingle ||
     165             :       offset > bytecode_iterator.current_offset()) {
     166             :     OFStream os(stdout);
     167             :     // Print all output registers and accumulator.
     168             :     PrintRegisters(os, false, bytecode_iterator, accumulator);
     169             :     os << std::flush;
     170             :   }
     171             :   return isolate->heap()->undefined_value();
     172             : }
     173             : 
     174             : #endif
     175             : 
     176             : }  // namespace internal
     177             : }  // namespace v8

Generated by: LCOV version 1.10