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