1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime-utils.h"
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include <iomanip>
8109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/arguments.h"
10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/frames-inl.h"
11109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/bytecode-array-iterator.h"
12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/interpreter/bytecode-decoder.h"
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/interpreter/bytecode-flags.h"
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/interpreter/bytecode-register.h"
15109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/bytecodes.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h"
17109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/ostreams.h"
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(4, args.length());
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1);
2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CONVERT_SMI_ARG_CHECKED(index, 2);
2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CONVERT_SMI_ARG_CHECKED(pretenured_flag, 3);
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Context> context(isolate->context(), isolate);
3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FeedbackSlot slot = FeedbackVector::ToSlot(index);
3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate);
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      shared, context, vector_cell,
3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      static_cast<PretenureFlag>(pretenured_flag));
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
37109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace {
38109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid AdvanceToOffsetForTracing(
403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) {
413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  while (bytecode_iterator.current_offset() +
423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             bytecode_iterator.current_bytecode_size() <=
433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         offset) {
443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    bytecode_iterator.Advance();
453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(bytecode_iterator.current_offset() == offset ||
473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         ((bytecode_iterator.current_offset() + 1) == offset &&
483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          bytecode_iterator.current_operand_scale() >
493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              interpreter::OperandScale::kSingle));
503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
52109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid PrintRegisters(std::ostream& os, bool is_input,
533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    interpreter::BytecodeArrayIterator& bytecode_iterator,
54109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                    Handle<Object> accumulator) {
553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static const char kAccumulator[] = "accumulator";
563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static const int kRegFieldWidth = static_cast<int>(sizeof(kAccumulator) - 1);
57109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static const char* kInputColourCode = "\033[0;36m";
58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static const char* kOutputColourCode = "\033[0;35m";
59109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static const char* kNormalColourCode = "\033[0;m";
60109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const char* kArrowDirection = is_input ? " -> " : " <- ";
61109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (FLAG_log_colour) {
62109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    os << (is_input ? kInputColourCode : kOutputColourCode);
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
67109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Print accumulator.
683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    os << "      [ " << kAccumulator << kArrowDirection;
713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    accumulator->ShortPrint();
723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    os << " ]" << std::endl;
733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
74109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
75bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Print the registers.
763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  JavaScriptFrameIterator frame_iterator(
773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      bytecode_iterator.bytecode_array()->GetIsolate());
78bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InterpretedFrame* frame =
79bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      reinterpret_cast<InterpretedFrame*>(frame_iterator.frame());
80109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
81109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int operand_index = 0; operand_index < operand_count; operand_index++) {
82109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    interpreter::OperandType operand_type =
83109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
84109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bool should_print =
85109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        is_input
86109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
87109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
88109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (should_print) {
89109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      interpreter::Register first_reg =
90109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          bytecode_iterator.GetRegisterOperand(operand_index);
91109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      for (int reg_index = first_reg.index();
93109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           reg_index < first_reg.index() + range; reg_index++) {
94bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Object* reg_object = frame->ReadInterpreterRegister(reg_index);
95109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        os << "      [ " << std::setw(kRegFieldWidth)
96109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           << interpreter::Register(reg_index).ToString(
973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  bytecode_iterator.bytecode_array()->parameter_count())
98109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           << kArrowDirection;
99109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        reg_object->ShortPrint(os);
100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        os << " ]" << std::endl;
101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (FLAG_log_colour) {
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    os << kNormalColourCode;
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SealHandleScope shs(isolate);
113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(3, args.length());
114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
115109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OFStream os(stdout);
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
1213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  AdvanceToOffsetForTracing(bytecode_iterator, offset);
1223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (offset == bytecode_iterator.current_offset()) {
1233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Print bytecode.
124bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const uint8_t* base_address = bytecode_array->GetFirstBytecodeAddress();
125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const uint8_t* bytecode_address = base_address + offset;
126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    os << " -> " << static_cast<const void*>(bytecode_address) << " @ "
127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch       << std::setw(4) << offset << " : ";
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    interpreter::BytecodeDecoder::Decode(os, bytecode_address,
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         bytecode_array->parameter_count());
1303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    os << std::endl;
1313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Print all input registers and accumulator.
1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PrintRegisters(os, true, bytecode_iterator, accumulator);
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    os << std::flush;
1353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return isolate->heap()->undefined_value();
137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SealHandleScope shs(isolate);
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(3, args.length());
142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
1483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  AdvanceToOffsetForTracing(bytecode_iterator, offset);
1493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The offset comparison here ensures registers only printed when the
1503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // (potentially) widened bytecode has completed. The iterator reports
1513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // the offset as the offset of the prefix bytecode.
1523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (bytecode_iterator.current_operand_scale() ==
1533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          interpreter::OperandScale::kSingle ||
1543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      offset > bytecode_iterator.current_offset()) {
1553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    OFStream os(stdout);
1563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Print all output registers and accumulator.
1573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PrintRegisters(os, false, bytecode_iterator, accumulator);
1583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    os << std::flush;
1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return isolate->heap()->undefined_value();
161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochRUNTIME_FUNCTION(Runtime_InterpreterAdvanceBytecodeOffset) {
164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SealHandleScope shs(isolate);
165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(2, args.length());
166c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  interpreter::BytecodeArrayIterator it(bytecode_array);
169c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
170c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  while (it.current_offset() < offset) it.Advance();
171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(offset, it.current_offset());
172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  it.Advance();  // Advance by one bytecode.
173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  offset = it.current_offset() + BytecodeArray::kHeaderSize - kHeapObjectTag;
174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Smi::FromInt(offset);
175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
176c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
179