blob: 7150a8b2873a734ad7d48b76c16b53a060fd3426 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdoch097c5b22016-05-18 11:27:45 +01007#include <iomanip>
8
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/arguments.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010010#include "src/frames-inl.h"
11#include "src/interpreter/bytecode-array-iterator.h"
12#include "src/interpreter/bytecodes.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/isolate-inl.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010014#include "src/ostreams.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015
16namespace v8 {
17namespace internal {
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) {
20 SealHandleScope shs(isolate);
21 DCHECK_EQ(1, args.length());
22 CONVERT_ARG_CHECKED(Object, x, 0);
23 return isolate->heap()->ToBoolean(x->BooleanValue());
24}
25
26
27RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot) {
28 SealHandleScope shs(isolate);
29 DCHECK_EQ(1, args.length());
30 CONVERT_ARG_CHECKED(Object, x, 0);
31 return isolate->heap()->ToBoolean(!x->BooleanValue());
32}
33
34
35RUNTIME_FUNCTION(Runtime_InterpreterTypeOf) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010036 HandleScope shs(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 DCHECK_EQ(1, args.length());
38 CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
39 return Object::cast(*Object::TypeOf(isolate, x));
40}
41
42
43RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
44 HandleScope scope(isolate);
45 DCHECK_EQ(2, args.length());
46 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
47 CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1);
48 Handle<Context> context(isolate->context(), isolate);
49 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
50 shared, context, static_cast<PretenureFlag>(pretenured_flag));
51}
52
Ben Murdoch097c5b22016-05-18 11:27:45 +010053namespace {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054
Ben Murdoch097c5b22016-05-18 11:27:45 +010055void PrintRegisters(std::ostream& os, bool is_input,
56 Handle<BytecodeArray> bytecode_array, int bytecode_offset,
57 Handle<Object> accumulator) {
58 static const int kRegFieldWidth = static_cast<int>(strlen("accumulator"));
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 // Print accumulator.
68 os << " [ accumulator" << kArrowDirection;
69 accumulator->ShortPrint();
70 os << " ]" << std::endl;
71
72 // Find the location of the register file.
73 JavaScriptFrameIterator frame_iterator(bytecode_array->GetIsolate());
74 JavaScriptFrame* frame = frame_iterator.frame();
75 Address register_file =
76 frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp;
77
78 // Print the registers.
79 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
80 bytecode_iterator.set_current_offset(
81 bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag);
82 interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
83 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
84 for (int operand_index = 0; operand_index < operand_count; operand_index++) {
85 interpreter::OperandType operand_type =
86 interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
87 bool should_print =
88 is_input
89 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
90 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
91 if (should_print) {
92 interpreter::Register first_reg =
93 bytecode_iterator.GetRegisterOperand(operand_index);
94 int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
95 for (int reg_index = first_reg.index();
96 reg_index < first_reg.index() + range; reg_index++) {
97 Address reg_location = register_file - reg_index * kPointerSize;
98 Object* reg_object = Memory::Object_at(reg_location);
99 os << " [ " << std::setw(kRegFieldWidth)
100 << interpreter::Register(reg_index).ToString(
101 bytecode_array->parameter_count())
102 << kArrowDirection;
103 reg_object->ShortPrint(os);
104 os << " ]" << std::endl;
105 }
106 }
107 }
108 if (FLAG_log_colour) {
109 os << kNormalColourCode;
110 }
111}
112
113} // namespace
114
115RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
116 SealHandleScope shs(isolate);
117 DCHECK_EQ(3, args.length());
118 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
119 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
120 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
121 OFStream os(stdout);
122
123 // Print bytecode.
124 const uint8_t* bytecode_address =
125 reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset;
126 Vector<char> buf = Vector<char>::New(50);
127 SNPrintF(buf, "%p", bytecode_address);
128 os << " -> " << buf.start() << " (" << bytecode_offset << ") : ";
129 interpreter::Bytecodes::Decode(os, bytecode_address,
130 bytecode_array->parameter_count());
131 os << std::endl;
132
133 // Print all input registers and accumulator.
134 PrintRegisters(os, true, bytecode_array, bytecode_offset, accumulator);
135
136 os << std::flush;
137 return isolate->heap()->undefined_value();
138}
139
140RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
141 SealHandleScope shs(isolate);
142 DCHECK_EQ(3, args.length());
143 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
144 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
145 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
146 OFStream os(stdout);
147
148 // Print all output registers and accumulator.
149 PrintRegisters(os, false, bytecode_array, bytecode_offset, accumulator);
150 os << std::flush;
151 return isolate->heap()->undefined_value();
152}
153
154RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) {
155 SealHandleScope shs(isolate);
156 DCHECK_EQ(0, args.length());
157 Object* message = isolate->thread_local_top()->pending_message_obj_;
158 isolate->clear_pending_message();
159 return message;
160}
161
162RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) {
163 SealHandleScope shs(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 DCHECK_EQ(1, args.length());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100165 CONVERT_ARG_HANDLE_CHECKED(Object, message, 0);
166 isolate->thread_local_top()->pending_message_obj_ = *message;
167 return isolate->heap()->undefined_value();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000168}
169
170} // namespace internal
171} // namespace v8