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

Generated by: LCOV version 1.10