1109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// found in the LICENSE file. 4109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 5109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/interpreter-assembler.h" 6109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 7bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include <limits> 8109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include <ostream> 9109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/code-factory.h" 11109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/frames.h" 12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interface-descriptors.h" 13109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/bytecodes.h" 14109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/interpreter.h" 15109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/machine-type.h" 16109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/macro-assembler.h" 1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 18f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone.h" 19109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 20109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace v8 { 21109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace internal { 22109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace interpreter { 23109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochusing compiler::CodeAssemblerState; 25109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochusing compiler::Node; 26109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochInterpreterAssembler::InterpreterAssembler(CodeAssemblerState* state, 283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecode bytecode, 293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandScale operand_scale) 3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : CodeStubAssembler(state), 31109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bytecode_(bytecode), 323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch operand_scale_(operand_scale), 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bytecode_offset_(this, MachineType::PointerRepresentation()), 3413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch interpreted_frame_pointer_(this, MachineType::PointerRepresentation()), 3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytecode_array_(this, MachineRepresentation::kTagged), 3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch dispatch_table_(this, MachineType::PointerRepresentation()), 37109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator_(this, MachineRepresentation::kTagged), 383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch accumulator_use_(AccumulatorUse::kNone), 39bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch made_call_(false), 4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reloaded_frame_ptr_(false), 4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch saved_bytecode_offset_(false), 42109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch disable_stack_check_across_call_(false), 43109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch stack_pointer_before_call_(nullptr) { 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch accumulator_.Bind(Parameter(InterpreterDispatchDescriptor::kAccumulator)); 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bytecode_offset_.Bind( 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Parameter(InterpreterDispatchDescriptor::kBytecodeOffset)); 4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytecode_array_.Bind( 4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Parameter(InterpreterDispatchDescriptor::kBytecodeArray)); 4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch dispatch_table_.Bind( 5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Parameter(InterpreterDispatchDescriptor::kDispatchTable)); 5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 52109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_trace_ignition) { 53109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); 54109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch RegisterCallGenerationCallbacks([this] { CallPrologue(); }, 5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch [this] { CallEpilogue(); }); 57109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochInterpreterAssembler::~InterpreterAssembler() { 603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If the following check fails the handler does not use the 613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // accumulator in the way described in the bytecode definitions in 623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // bytecodes.h. 633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); 6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UnregisterCallGenerationCallbacks(); 653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 6713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* InterpreterAssembler::GetInterpretedFramePointer() { 6813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!interpreted_frame_pointer_.IsBound()) { 6913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch interpreted_frame_pointer_.Bind(LoadParentFramePointer()); 7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (Bytecodes::MakesCallAlongCriticalPath(bytecode_) && made_call_ && 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !reloaded_frame_ptr_) { 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch interpreted_frame_pointer_.Bind(LoadParentFramePointer()); 7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reloaded_frame_ptr_ = true; 7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return interpreted_frame_pointer_.value(); 7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::GetAccumulatorUnchecked() { 793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return accumulator_.value(); 803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 81109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::GetAccumulator() { 833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(Bytecodes::ReadsAccumulator(bytecode_)); 843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch accumulator_use_ = accumulator_use_ | AccumulatorUse::kRead; 853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return GetAccumulatorUnchecked(); 863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 87109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 88109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::SetAccumulator(Node* value) { 893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(Bytecodes::WritesAccumulator(bytecode_)); 903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch accumulator_use_ = accumulator_use_ | AccumulatorUse::kWrite; 91109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator_.Bind(value); 92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 93109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 94bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::GetContext() { 95bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return LoadRegister(Register::current_context()); 96bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 97109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 98109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::SetContext(Node* value) { 99109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch StoreRegister(value, Register::current_context()); 100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* InterpreterAssembler::GetContextAtDepth(Node* context, Node* depth) { 103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable cur_context(this, MachineRepresentation::kTaggedPointer); 104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_context.Bind(context); 105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable cur_depth(this, MachineRepresentation::kWord32); 107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_depth.Bind(depth); 108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Label context_found(this); 110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; 112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Label context_search(this, 2, context_search_loop_variables); 113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Fast path if the depth is 0. 115c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(Word32Equal(depth, Int32Constant(0)), &context_found, &context_search); 116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Loop until the depth is 0. 118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&context_search); 119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_depth.Bind(Int32Sub(cur_depth.value(), Int32Constant(1))); 121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_context.Bind( 122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadContextElement(cur_context.value(), Context::PREVIOUS_INDEX)); 123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(Word32Equal(cur_depth.value(), Int32Constant(0)), &context_found, 125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch &context_search); 126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&context_found); 129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return cur_context.value(); 130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 132f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InterpreterAssembler::GotoIfHasContextExtensionUpToDepth(Node* context, 133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* depth, 134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Label* target) { 135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable cur_context(this, MachineRepresentation::kTaggedPointer); 136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_context.Bind(context); 137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable cur_depth(this, MachineRepresentation::kWord32); 139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_depth.Bind(depth); 140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; 142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Label context_search(this, 2, context_search_loop_variables); 143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Loop until the depth is 0. 145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&context_search); 146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&context_search); 147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(leszeks): We only need to do this check if the context had a sloppy 149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // eval, we could pass in a context chain bitmask to figure out which 150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // contexts actually need to be checked. 151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* extension_slot = 153c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadContextElement(cur_context.value(), Context::EXTENSION_INDEX); 154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Jump to the target if the extension slot is not a hole. 156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GotoIf(WordNotEqual(extension_slot, TheHoleConstant()), target); 157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_depth.Bind(Int32Sub(cur_depth.value(), Int32Constant(1))); 159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cur_context.Bind( 160c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadContextElement(cur_context.value(), Context::PREVIOUS_INDEX)); 161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GotoIf(Word32NotEqual(cur_depth.value(), Int32Constant(0)), 163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch &context_search); 164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::BytecodeOffset() { 16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::MakesCallAlongCriticalPath(bytecode_) && made_call_ && 16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (bytecode_offset_.value() == 17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Parameter(InterpreterDispatchDescriptor::kBytecodeOffset))) { 17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytecode_offset_.Bind(LoadAndUntagRegister(Register::bytecode_offset())); 17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return bytecode_offset_.value(); 174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::BytecodeArrayTaggedPointer() { 17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Force a re-load of the bytecode array after every call in case the debugger 17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // has been activated. 17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (made_call_ && 18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (bytecode_array_.value() == 18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Parameter(InterpreterDispatchDescriptor::kBytecodeArray))) { 18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytecode_array_.Bind(LoadRegister(Register::bytecode_array())); 183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return bytecode_array_.value(); 185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::DispatchTableRawPointer() { 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::MakesCallAlongCriticalPath(bytecode_) && made_call_ && 18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (dispatch_table_.value() == 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Parameter(InterpreterDispatchDescriptor::kDispatchTable))) { 19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch dispatch_table_.Bind(ExternalConstant( 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::interpreter_dispatch_table_address(isolate()))); 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return dispatch_table_.value(); 195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::RegisterLocation(Node* reg_index) { 19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntPtrAdd(GetInterpretedFramePointer(), 19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RegisterFrameOffset(reg_index)); 200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::RegisterFrameOffset(Node* index) { 203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return WordShl(index, kPointerSizeLog2); 204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::LoadRegister(Register reg) { 20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Load(MachineType::AnyTagged(), GetInterpretedFramePointer(), 208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IntPtrConstant(reg.ToOperand() << kPointerSizeLog2)); 209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::LoadRegister(Node* reg_index) { 21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Load(MachineType::AnyTagged(), GetInterpretedFramePointer(), 213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RegisterFrameOffset(reg_index)); 214109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::LoadAndUntagRegister(Register reg) { 21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return LoadAndUntagSmi(GetInterpretedFramePointer(), reg.ToOperand() 21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch << kPointerSizeLog2); 21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::StoreRegister(Node* value, Register reg) { 222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return StoreNoWriteBarrier( 22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MachineRepresentation::kTagged, GetInterpretedFramePointer(), 224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IntPtrConstant(reg.ToOperand() << kPointerSizeLog2), value); 225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { 228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return StoreNoWriteBarrier(MachineRepresentation::kTagged, 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetInterpretedFramePointer(), 230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RegisterFrameOffset(reg_index), value); 231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::StoreAndTagRegister(compiler::Node* value, 23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Register reg) { 23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int offset = reg.ToOperand() << kPointerSizeLog2; 23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return StoreAndTagSmi(GetInterpretedFramePointer(), offset, value); 23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::NextRegister(Node* reg_index) { 240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Register indexes are negative, so the next index is minus one. 2413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return IntPtrAdd(reg_index, IntPtrConstant(-1)); 2423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 2433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::OperandOffset(int operand_index) { 2453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return IntPtrConstant( 2463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale())); 247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandUnsignedByte(int operand_index) { 250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( 2523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bytecode_, operand_index, operand_scale())); 2533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* operand_offset = OperandOffset(operand_index); 2543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), 2553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrAdd(BytecodeOffset(), operand_offset)); 256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandSignedByte(int operand_index) { 259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 2603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( 2613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bytecode_, operand_index, operand_scale())); 2623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* operand_offset = OperandOffset(operand_index); 26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Load(MachineType::Int8(), BytecodeArrayTaggedPointer(), 26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IntPtrAdd(BytecodeOffset(), operand_offset)); 265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochcompiler::Node* InterpreterAssembler::BytecodeOperandReadUnaligned( 2683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int relative_offset, MachineType result_type) { 2693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static const int kMaxCount = 4; 2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!TargetSupportsUnalignedAccess()); 2713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int count; 2733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (result_type.representation()) { 2743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case MachineRepresentation::kWord16: 2753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch count = 2; 2763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 2773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case MachineRepresentation::kWord32: 2783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch count = 4; 2793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 2803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch default: 2813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UNREACHABLE(); 2823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 2833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineType msb_type = 2853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result_type.IsSigned() ? MachineType::Int8() : MachineType::Uint8(); 2863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#if V8_TARGET_LITTLE_ENDIAN 2883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kStep = -1; 2893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int msb_offset = count - 1; 290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#elif V8_TARGET_BIG_ENDIAN 2913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kStep = 1; 2923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int msb_offset = 0; 293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#else 294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#error "Unknown Architecture" 295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif 2963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Read the most signicant bytecode into bytes[0] and then in order 2983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // down to least significant in bytes[count - 1]. 2993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(count <= kMaxCount); 3003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch compiler::Node* bytes[kMaxCount]; 3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 0; i < count; i++) { 3023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineType machine_type = (i == 0) ? msb_type : MachineType::Uint8(); 3033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* offset = IntPtrConstant(relative_offset + msb_offset + i * kStep); 3043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* array_offset = IntPtrAdd(BytecodeOffset(), offset); 3053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bytes[i] = Load(machine_type, BytecodeArrayTaggedPointer(), array_offset); 3063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Pack LSB to MSB. 3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* result = bytes[--count]; 3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 1; --count >= 0; i++) { 3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* shift = Int32Constant(i * kBitsPerByte); 3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* value = Word32Shl(bytes[count], shift); 3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result = Word32Or(value, result); 314109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return result; 316109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 317109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandUnsignedShort(int operand_index) { 319109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 3203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ( 3213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize::kShort, 3223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale())); 3233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int operand_offset = 3243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); 3253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (TargetSupportsUnalignedAccess()) { 3263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Load(MachineType::Uint16(), BytecodeArrayTaggedPointer(), 3273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); 3283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 3293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint16()); 3303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandSignedShort(int operand_index) { 3343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 3353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ( 3363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize::kShort, 3373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale())); 3383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int operand_offset = 3393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); 340109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (TargetSupportsUnalignedAccess()) { 34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Load(MachineType::Int16(), BytecodeArrayTaggedPointer(), 3423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); 343109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return BytecodeOperandReadUnaligned(operand_offset, MachineType::Int16()); 345109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandUnsignedQuad(int operand_index) { 3493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 3503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize( 3513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bytecode_, operand_index, operand_scale())); 3523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int operand_offset = 3533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); 3543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (TargetSupportsUnalignedAccess()) { 3553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Load(MachineType::Uint32(), BytecodeArrayTaggedPointer(), 3563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); 3573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 3583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint32()); 3593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandSignedQuad(int operand_index) { 3633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); 3643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize( 3653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bytecode_, operand_index, operand_scale())); 3663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int operand_offset = 3673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()); 3683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (TargetSupportsUnalignedAccess()) { 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), 3703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset))); 3713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return BytecodeOperandReadUnaligned(operand_offset, MachineType::Int32()); 3733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeSignedOperand(int operand_index, 3773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size) { 3783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!Bytecodes::IsUnsignedOperandType( 3793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index))); 3803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (operand_size) { 381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kByte: 3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandSignedByte(operand_index); 383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kShort: 3843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandSignedShort(operand_index); 3853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case OperandSize::kQuad: 3863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandSignedQuad(operand_index); 387109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kNone: 388109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch UNREACHABLE(); 389109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return nullptr; 391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 392109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeUnsignedOperand(int operand_index, 3943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size) { 3953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(Bytecodes::IsUnsignedOperandType( 3963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index))); 3973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (operand_size) { 398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kByte: 3993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandUnsignedByte(operand_index); 400109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kShort: 4013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandUnsignedShort(operand_index); 4023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case OperandSize::kQuad: 4033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeOperandUnsignedQuad(operand_index); 404109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case OperandSize::kNone: 405109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch UNREACHABLE(); 406109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 407109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return nullptr; 408109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 409109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandCount(int operand_index) { 4113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandType::kRegCount, 4123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 4133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 4153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeUnsignedOperand(operand_index, operand_size); 4163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandFlag(int operand_index) { 4193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandType::kFlag8, 4203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 4213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(operand_size, OperandSize::kByte); 4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeUnsignedOperand(operand_index, operand_size); 4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* InterpreterAssembler::BytecodeOperandUImm(int operand_index) { 428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(OperandType::kUImm, 429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch OperandSize operand_size = 431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return BytecodeUnsignedOperand(operand_index, operand_size); 433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 43562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::BytecodeOperandUImmWord(int operand_index) { 43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ChangeUint32ToWord(BytecodeOperandUImm(operand_index)); 43762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 43862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandImm(int operand_index) { 4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(OperandType::kImm, 4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeSignedOperand(operand_index, operand_size); 4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::BytecodeOperandImmIntPtr(int operand_index) { 44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ChangeInt32ToIntPtr(BytecodeOperandImm(operand_index)); 44962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::BytecodeOperandImmSmi(int operand_index) { 45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return SmiFromWord32(BytecodeOperandImm(operand_index)); 45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 45462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { 4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(OperandType::kIdx == 4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ChangeUint32ToWord( 46162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BytecodeUnsignedOperand(operand_index, operand_size)); 46262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 46362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 46462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::BytecodeOperandIdxSmi(int operand_index) { 46562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return SmiTag(BytecodeOperandIdx(operand_index)); 4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::BytecodeOperandReg(int operand_index) { 4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(Bytecodes::IsRegisterOperandType( 4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index))); 4713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ChangeInt32ToIntPtr( 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BytecodeSignedOperand(operand_index, operand_size)); 4753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) { 4783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(OperandType::kRuntimeId == 4793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 4803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OperandSize operand_size = 4813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 4823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(operand_size, OperandSize::kShort); 4833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return BytecodeUnsignedOperand(operand_index, operand_size); 484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 48613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* InterpreterAssembler::BytecodeOperandIntrinsicId(int operand_index) { 48713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(OperandType::kIntrinsicId == 48813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Bytecodes::GetOperandType(bytecode_, operand_index)); 48913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OperandSize operand_size = 49013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()); 49113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(operand_size, OperandSize::kByte); 49213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return BytecodeUnsignedOperand(operand_index, operand_size); 49313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 49413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { 496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), 497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BytecodeArray::kConstantPoolOffset); 49862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return LoadFixedArrayElement(constant_pool, index); 499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::LoadAndUntagConstantPoolEntry(Node* index) { 50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return SmiUntag(LoadConstantPoolEntry(index)); 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::LoadFeedbackVector() { 506bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* function = LoadRegister(Register::function_closure()); 50762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* cell = LoadObjectField(function, JSFunction::kFeedbackVectorOffset); 50862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* vector = LoadObjectField(cell, Cell::kValueOffset); 509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return vector; 510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InterpreterAssembler::SaveBytecodeOffset() { 51362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 51462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StoreAndTagRegister(BytecodeOffset(), Register::bytecode_offset()); 51562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch saved_bytecode_offset_ = true; 51662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::CallPrologue() { 51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!saved_bytecode_offset_) { 52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // If there are multiple calls in the bytecode handler, you need to spill 52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // before each of them, unless SaveBytecodeOffset has explicitly been called 52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // in a path that dominates _all_ of those calls. Therefore don't set 52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // saved_bytecode_offset_ to true or call SaveBytecodeOffset. 52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StoreAndTagRegister(BytecodeOffset(), Register::bytecode_offset()); 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_debug_code && !disable_stack_check_across_call_) { 528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(stack_pointer_before_call_ == nullptr); 529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch stack_pointer_before_call_ = LoadStackPointer(); 530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 531bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch made_call_ = true; 532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::CallEpilogue() { 535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_debug_code && !disable_stack_check_across_call_) { 536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stack_pointer_after_call = LoadStackPointer(); 537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stack_pointer_before_call = stack_pointer_before_call_; 538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch stack_pointer_before_call_ = nullptr; 539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, 540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch kUnexpectedStackPointer); 541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::IncrementCallCount(Node* feedback_vector, 545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* slot_id) { 546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Comment("increment call count"); 547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); 54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* call_count = LoadFixedArrayElement(feedback_vector, call_count_slot); 54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* new_count = SmiAdd(call_count, SmiConstant(1)); 550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Count is Smi, so we don't need a write barrier. 55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return StoreFixedArrayElement(feedback_vector, call_count_slot, new_count, 55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SKIP_WRITE_BARRIER); 553f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, 556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* first_arg, Node* arg_count, 557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* slot_id, 55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* feedback_vector, 559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TailCallMode tail_call_mode) { 560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Static checks to assert it is safe to examine the type feedback element. 561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We don't know that we have a weak cell. We might have a private symbol 562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // or an AllocationSite, but the memory is safe to examine. 563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to 564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FixedArray. 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // WeakCell::kValueOffset - contains a JSFunction or Smi(0) 566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not 567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // computed, meaning that it can't appear to be a pointer. If the low bit is 568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // 0, then hash is computed, but the 0 bit prevents the field from appearing 569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // to be a pointer. 57062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 57162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::IsCallOrConstruct(bytecode_)); 572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_ASSERT(WeakCell::kSize >= kPointerSize); 573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == 574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch WeakCell::kValueOffset && 575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch WeakCell::kValueOffset == Symbol::kHashFieldSlot); 576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Variable return_value(this, MachineRepresentation::kTagged); 578c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label call_function(this), extra_checks(this, Label::kDeferred), call(this), 579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch end(this); 580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The checks. First, does function match the recorded monomorphic target? 58262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* feedback_element = LoadFixedArrayElement(feedback_vector, slot_id); 583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element); 584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_monomorphic = WordEqual(function, feedback_value); 58562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_monomorphic, &extra_checks); 586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 587c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The compare above could have been a SMI/SMI comparison. Guard against 588c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // this convincing us that we have a monomorphic JSFunction. 589c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_smi = TaggedIsSmi(function); 590c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_smi, &extra_checks, &call_function); 591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 592c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&call_function); 593c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Increment the call count. 59562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IncrementCallCount(feedback_vector, slot_id); 596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Call using call function builtin. 598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::InterpreterPushArgsAndCall( 59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), tail_call_mode, InterpreterPushArgsMode::kJSFunction); 600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* code_target = HeapConstant(callable.code()); 601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* ret_value = CallStub(callable.descriptor(), code_target, context, 602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch arg_count, first_arg, function); 603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_value.Bind(ret_value); 604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&end); 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&extra_checks); 608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 609c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label check_initialized(this), mark_megamorphic(this), 610c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch create_allocation_site(this); 611c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 612c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if megamorphic"); 613c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if it is a megamorphic target. 61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* is_megamorphic = 61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WordEqual(feedback_element, 61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapConstant(FeedbackVector::MegamorphicSentinel(isolate()))); 617c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GotoIf(is_megamorphic, &call); 618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 619c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if it is an allocation site"); 62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(IsAllocationSiteMap(LoadMap(feedback_element)), 62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &check_initialized); 622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 623c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If it is not the Array() function, mark megamorphic. 62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context_slot = LoadContextElement(LoadNativeContext(context), 62562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Context::ARRAY_FUNCTION_INDEX); 626c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_array_function = WordEqual(context_slot, function); 62762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_array_function, &mark_megamorphic); 628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 629c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // It is a monomorphic Array function. Increment the call count. 63062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IncrementCallCount(feedback_vector, slot_id); 631c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 632c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Call ArrayConstructorStub. 633c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable_call = 634c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CodeFactory::InterpreterPushArgsAndConstructArray(isolate()); 635c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* code_target_call = HeapConstant(callable_call.code()); 636c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* ret_value = 637c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CallStub(callable_call.descriptor(), code_target_call, context, 638c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch arg_count, function, feedback_element, first_arg); 639c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return_value.Bind(ret_value); 640c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&end); 641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&check_initialized); 643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 644c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if uninitialized"); 645c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if it is uninitialized target first. 646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_uninitialized = WordEqual( 647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch feedback_element, 64862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapConstant(FeedbackVector::UninitializedSentinel(isolate()))); 64962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_uninitialized, &mark_megamorphic); 650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 651c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("handle_unitinitialized"); 652c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If it is not a JSFunction mark it as megamorphic. 653c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_smi = TaggedIsSmi(function); 654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GotoIf(is_smi, &mark_megamorphic); 655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 656c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if function is an object of JSFunction type. 657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* instance_type = LoadInstanceType(function); 658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_js_function = 65962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Word32Equal(instance_type, Int32Constant(JS_FUNCTION_TYPE)); 66062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_js_function, &mark_megamorphic); 661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if it is the Array() function. 66362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context_slot = LoadContextElement(LoadNativeContext(context), 66462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Context::ARRAY_FUNCTION_INDEX); 665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_array_function = WordEqual(context_slot, function); 666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GotoIf(is_array_function, &create_allocation_site); 667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 668c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if the function belongs to the same native context. 669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* native_context = LoadNativeContext( 670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LoadObjectField(function, JSFunction::kContextOffset)); 671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_same_native_context = 672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch WordEqual(native_context, LoadNativeContext(context)); 67362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_same_native_context, &mark_megamorphic); 674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateWeakCellInFeedbackVector(feedback_vector, SmiTag(slot_id), 676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch function); 677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Call using call function builtin. 679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&call_function); 680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&create_allocation_site); 683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 68462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateAllocationSiteInFeedbackVector(feedback_vector, SmiTag(slot_id)); 685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Call using CallFunction builtin. CallICs have a PREMONOMORPHIC state. 687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // They start collecting feedback only when a call is executed the second 688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // time. So, do not pass any feedback here. 689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&call_function); 690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&mark_megamorphic); 693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Mark it as a megamorphic. 695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // MegamorphicSentinel is created as a part of Heap::InitialObjects 696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // and will not move during a GC. So it is safe to skip write barrier. 697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex)); 698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StoreFixedArrayElement( 69962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch feedback_vector, slot_id, 70062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())), 701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SKIP_WRITE_BARRIER); 702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&call); 703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&call); 707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("Increment call count and call using Call builtin"); 709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Increment the call count. 71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IncrementCallCount(feedback_vector, slot_id); 711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Call using call builtin. 713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( 71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), tail_call_mode, InterpreterPushArgsMode::kOther); 715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* code_target_call = HeapConstant(callable_call.code()); 716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, 717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context, arg_count, first_arg, function); 718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Bind(ret_value); 719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&end); 720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&end); 723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return return_value.value(); 724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::CallJS(Node* function, Node* context, 727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* first_arg, Node* arg_count, 728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch TailCallMode tail_call_mode) { 72962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 73062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::IsCallOrConstruct(bytecode_)); 731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::InterpreterPushArgsAndCall( 73262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), tail_call_mode, InterpreterPushArgsMode::kOther); 733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* code_target = HeapConstant(callable.code()); 73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return CallStub(callable.descriptor(), code_target, context, arg_count, 736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch first_arg, function); 737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 738109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::CallJSWithSpread(Node* function, Node* context, 74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* first_arg, Node* arg_count) { 74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 74262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::InterpreterPushArgsAndCall( 74362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), TailCallMode::kDisallow, 74462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InterpreterPushArgsMode::kWithFinalSpread); 74562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* code_target = HeapConstant(callable.code()); 74662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 74762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return CallStub(callable.descriptor(), code_target, context, arg_count, 74862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch first_arg, function); 74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::Construct(Node* constructor, Node* context, 75262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* new_target, Node* first_arg, 75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* arg_count, Node* slot_id, 75462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* feedback_vector) { 75562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable return_value(this, MachineRepresentation::kTagged); 757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Variable allocation_feedback(this, MachineRepresentation::kTagged); 758c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label call_construct_function(this, &allocation_feedback), 759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch extra_checks(this, Label::kDeferred), call_construct(this), end(this); 760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Slot id of 0 is used to indicate no type feedback is available. 76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); 76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* is_feedback_unavailable = WordEqual(slot_id, IntPtrConstant(0)); 764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GotoIf(is_feedback_unavailable, &call_construct); 765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check that the constructor is not a smi. 767c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_smi = TaggedIsSmi(constructor); 768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GotoIf(is_smi, &call_construct); 769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check that constructor is a JSFunction. 771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* instance_type = LoadInstanceType(constructor); 772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* is_js_function = 77362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Word32Equal(instance_type, Int32Constant(JS_FUNCTION_TYPE)); 77462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_js_function, &call_construct); 775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 776c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if it is a monomorphic constructor. 77762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* feedback_element = LoadFixedArrayElement(feedback_vector, slot_id); 778c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element); 779c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_monomorphic = WordEqual(constructor, feedback_value); 780c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch allocation_feedback.Bind(UndefinedConstant()); 781c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_monomorphic, &call_construct_function, &extra_checks); 782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&call_construct_function); 784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Comment("call using ConstructFunction"); 78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IncrementCallCount(feedback_vector, slot_id); 787c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct( 78862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), InterpreterPushArgsMode::kJSFunction); 789c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return_value.Bind(CallStub(callable_function.descriptor(), 790c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HeapConstant(callable_function.code()), context, 791c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch arg_count, new_target, constructor, 792c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch allocation_feedback.value(), first_arg)); 793c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&end); 794c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 795c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 796c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&extra_checks); 797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 798c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label check_allocation_site(this), check_initialized(this), 799c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch initialize(this), mark_megamorphic(this); 800c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 801c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if it is a megamorphic target. 802c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if megamorphic"); 80362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* is_megamorphic = 80462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WordEqual(feedback_element, 80562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapConstant(FeedbackVector::MegamorphicSentinel(isolate()))); 806c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch GotoIf(is_megamorphic, &call_construct_function); 807c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 808c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if weak cell"); 809c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_weak_cell = WordEqual(LoadMap(feedback_element), 810c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadRoot(Heap::kWeakCellMapRootIndex)); 81162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_weak_cell, &check_allocation_site); 812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 813c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If the weak cell is cleared, we have a new chance to become 814c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // monomorphic. 815c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if weak cell is cleared"); 816c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_smi = TaggedIsSmi(feedback_value); 817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_smi, &initialize, &mark_megamorphic); 818c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 819c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&check_allocation_site); 820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 821c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if it is an allocation site"); 822c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_allocation_site = 823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch WordEqual(LoadObjectField(feedback_element, 0), 824c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadRoot(Heap::kAllocationSiteMapRootIndex)); 82562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_allocation_site, &check_initialized); 826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 827c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Make sure the function is the Array() function. 82862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context_slot = LoadContextElement(LoadNativeContext(context), 82962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Context::ARRAY_FUNCTION_INDEX); 830c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_array_function = WordEqual(context_slot, constructor); 83162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(is_array_function, &mark_megamorphic); 832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 833c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch allocation_feedback.Bind(feedback_element); 834c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&call_construct_function); 835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&check_initialized); 838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check if it is uninitialized. 840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("check if uninitialized"); 841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_uninitialized = WordEqual( 842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex)); 843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_uninitialized, &initialize, &mark_megamorphic); 844c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&initialize); 847c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label create_allocation_site(this), create_weak_cell(this); 849c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("initialize the feedback element"); 850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Create an allocation site if the function is an array function, 851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // otherwise create a weak cell. 85262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context_slot = LoadContextElement(LoadNativeContext(context), 85362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Context::ARRAY_FUNCTION_INDEX); 854c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_array_function = WordEqual(context_slot, constructor); 855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_array_function, &create_allocation_site, &create_weak_cell); 856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 857c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&create_allocation_site); 858c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 85962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* site = CreateAllocationSiteInFeedbackVector(feedback_vector, 860c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SmiTag(slot_id)); 861c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch allocation_feedback.Bind(site); 862c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&call_construct_function); 863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 865c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&create_weak_cell); 866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 86762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateWeakCellInFeedbackVector(feedback_vector, SmiTag(slot_id), 868c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch constructor); 869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&call_construct_function); 870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 873c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&mark_megamorphic); 874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 875c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // MegamorphicSentinel is an immortal immovable object so 876c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // write-barrier is not needed. 877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Comment("transition to megamorphic"); 878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex)); 879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch StoreFixedArrayElement( 88062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch feedback_vector, slot_id, 88162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())), 882c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SKIP_WRITE_BARRIER); 883c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&call_construct_function); 884f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&call_construct); 888f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Comment("call using Construct builtin"); 890f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Callable callable = CodeFactory::InterpreterPushArgsAndConstruct( 89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), InterpreterPushArgsMode::kOther); 892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* code_target = HeapConstant(callable.code()); 893f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Bind(CallStub(callable.descriptor(), code_target, context, 894f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch arg_count, new_target, constructor, 895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UndefinedConstant(), first_arg)); 896f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Goto(&end); 897f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 898f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Bind(&end); 900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return return_value.value(); 901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 90362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::ConstructWithSpread(Node* constructor, 90462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context, Node* new_target, 90562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* first_arg, 90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* arg_count) { 90762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 90862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Variable return_value(this, MachineRepresentation::kTagged); 90962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Comment("call using ConstructWithSpread"); 91062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::InterpreterPushArgsAndConstruct( 91162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), InterpreterPushArgsMode::kWithFinalSpread); 91262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* code_target = HeapConstant(callable.code()); 91362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return_value.Bind(CallStub(callable.descriptor(), code_target, context, 91462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch arg_count, new_target, constructor, 91562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UndefinedConstant(), first_arg)); 91662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 91762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return return_value.value(); 91862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 91962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 920109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context, 921109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* first_arg, Node* arg_count, 922109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int result_size) { 92362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); 92462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(Bytecodes::IsCallRuntime(bytecode_)); 925109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::InterpreterCEntry(isolate(), result_size); 926109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* code_target = HeapConstant(callable.code()); 927109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 928109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Get the function entry from the function id. 929109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* function_table = ExternalConstant( 930109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ExternalReference::runtime_function_table_address(isolate())); 931109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* function_offset = 932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); 93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* function = 93462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); 935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* function_entry = 936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Load(MachineType::Pointer(), function, 9373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IntPtrConstant(offsetof(Runtime::Function, entry))); 938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 93962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return CallStubR(callable.descriptor(), result_size, code_target, context, 94062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch arg_count, first_arg, function_entry); 941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 942109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 94362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) { 944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label ok(this), interrupt_check(this, Label::kDeferred), end(this); 945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* budget_offset = 946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); 947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Update budget by |weight| and check if it reaches zero. 949bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Variable new_budget(this, MachineRepresentation::kWord32); 950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* old_budget = 951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); 95262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (backward) { 95362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new_budget.Bind(Int32Sub(old_budget, weight)); 95462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 95562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new_budget.Bind(Int32Add(old_budget, weight)); 95662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 957bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* condition = 958bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); 959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Branch(condition, &ok, &interrupt_check); 960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Perform interrupt and reset budget. 962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bind(&interrupt_check); 963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch { 964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallRuntime(Runtime::kInterrupt, GetContext()); 965bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch new_budget.Bind(Int32Constant(Interpreter::InterruptBudget())); 966bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&ok); 967bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 969109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Update budget. 970109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bind(&ok); 971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch StoreNoWriteBarrier(MachineRepresentation::kWord32, 972bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch BytecodeArrayTaggedPointer(), budget_offset, 973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch new_budget.value()); 974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::Advance() { 977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Advance(Bytecodes::Size(bytecode_, operand_scale_)); 978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* InterpreterAssembler::Advance(int delta) { 981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Advance(IntPtrConstant(delta)); 982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 98462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::Advance(Node* delta, bool backward) { 985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_trace_ignition) { 986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); 987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 98862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* next_offset = backward ? IntPtrSub(BytecodeOffset(), delta) 98962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : IntPtrAdd(BytecodeOffset(), delta); 990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bytecode_offset_.Bind(next_offset); 991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return next_offset; 992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 99462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::Jump(Node* delta, bool backward) { 995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); 996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UpdateInterruptBudget(TruncateWordToWord32(delta), backward); 99862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* new_bytecode_offset = Advance(delta, backward); 999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* target_bytecode = LoadBytecode(new_bytecode_offset); 1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DispatchToBytecode(target_bytecode, new_bytecode_offset); 1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 100362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::Jump(Node* delta) { return Jump(delta, false); } 100462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 100562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* InterpreterAssembler::JumpBackward(Node* delta) { 100662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Jump(delta, true); 100762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 100862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { 1010bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label match(this), no_match(this); 1011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1012c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(condition, &match, &no_match); 1013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bind(&match); 1014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Jump(delta); 1015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bind(&no_match); 1016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Dispatch(); 1017109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1018109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1019109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { 1020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JumpConditional(WordEqual(lhs, rhs), delta); 1021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1023109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, 1024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* delta) { 1025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JumpConditional(WordNotEqual(lhs, rhs), delta); 1026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1027109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::LoadBytecode(compiler::Node* bytecode_offset) { 1029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* bytecode = 1030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), bytecode_offset); 103162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ChangeUint32ToWord(bytecode); 1032109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1034f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::StarDispatchLookahead(Node* target_bytecode) { 1035f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label do_inline_star(this), done(this); 1036f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1037c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Variable var_bytecode(this, MachineType::PointerRepresentation()); 1038f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_bytecode.Bind(target_bytecode); 1039f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1040f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* star_bytecode = IntPtrConstant(static_cast<int>(Bytecode::kStar)); 1041f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* is_star = WordEqual(target_bytecode, star_bytecode); 1042c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_star, &do_inline_star, &done); 1043f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&do_inline_star); 1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InlineStar(); 1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_bytecode.Bind(LoadBytecode(BytecodeOffset())); 1048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&done); 10493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1050f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&done); 1051f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return var_bytecode.value(); 1052f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1053f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1054f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InterpreterAssembler::InlineStar() { 1055f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bytecode previous_bytecode = bytecode_; 1056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AccumulatorUse previous_acc_use = accumulator_use_; 1057f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1058f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bytecode_ = Bytecode::kStar; 1059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch accumulator_use_ = AccumulatorUse::kNone; 1060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_trace_ignition) { 1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); 1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1064f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StoreRegister(GetAccumulator(), BytecodeOperandReg(0)); 1065f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1066f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); 1067f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1068f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Advance(); 1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bytecode_ = previous_bytecode; 1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch accumulator_use_ = previous_acc_use; 1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::Dispatch() { 107462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Comment("========= Dispatch"); 107562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_); 1076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* target_offset = Advance(); 1077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* target_bytecode = LoadBytecode(target_offset); 1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1079f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (Bytecodes::IsStarLookahead(bytecode_, operand_scale_)) { 1080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch target_bytecode = StarDispatchLookahead(target_bytecode); 1081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DispatchToBytecode(target_bytecode, BytecodeOffset()); 1083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1084109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::DispatchToBytecode(Node* target_bytecode, 1086f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* new_bytecode_offset) { 1087bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_trace_ignition_dispatches) { 1088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch TraceBytecodeDispatch(target_bytecode); 1089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1091bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* target_code_entry = 1092109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Load(MachineType::Pointer(), DispatchTableRawPointer(), 10933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2))); 1094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1095bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); 1096bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1097bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1098bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, 1099bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* bytecode_offset) { 110062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): Add CSA::CodeEntryPoint(code). 1101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* handler_entry = 110262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IntPtrAdd(BitcastTaggedToWord(handler), 110362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); 1104bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); 1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::DispatchToBytecodeHandlerEntry( 1108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* handler_entry, Node* bytecode_offset) { 1109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InterpreterDispatchDescriptor descriptor(isolate()); 111062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return TailCallBytecodeDispatch( 111162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch descriptor, handler_entry, GetAccumulatorUnchecked(), bytecode_offset, 111262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BytecodeArrayTaggedPointer(), DispatchTableRawPointer()); 1113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 11153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InterpreterAssembler::DispatchWide(OperandScale operand_scale) { 11163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Dispatching a wide bytecode requires treating the prefix 11173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // bytecode a base pointer into the dispatch table and dispatching 11183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the bytecode that follows relative to this base. 11193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // 11203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Indices 0-255 correspond to bytecodes with operand_scale == 0 11213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Indices 256-511 correspond to bytecodes with operand_scale == 1 11223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Indices 512-767 correspond to bytecodes with operand_scale == 2 112362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_); 11243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* next_bytecode_offset = Advance(1); 1125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* next_bytecode = LoadBytecode(next_bytecode_offset); 1126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_trace_ignition_dispatches) { 1128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch TraceBytecodeDispatch(next_bytecode); 1129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* base_index; 11323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (operand_scale) { 11333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case OperandScale::kDouble: 11343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch base_index = IntPtrConstant(1 << kBitsPerByte); 11353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 11363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case OperandScale::kQuadruple: 11373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch base_index = IntPtrConstant(2 << kBitsPerByte); 11383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 11393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch default: 11403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UNREACHABLE(); 11413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch base_index = nullptr; 11423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* target_index = IntPtrAdd(base_index, next_bytecode); 1144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* target_code_entry = 11453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Load(MachineType::Pointer(), DispatchTableRawPointer(), 11463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch WordShl(target_index, kPointerSizeLog2)); 11473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset); 11493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 11503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::TruncateTaggedToWord32WithFeedback( 1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* context, Node* value, Variable* var_type_feedback) { 1153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We might need to loop once due to ToNumber conversion. 1154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Variable var_value(this, MachineRepresentation::kTagged), 1155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_result(this, MachineRepresentation::kWord32); 1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Variable* loop_vars[] = {&var_value, var_type_feedback}; 1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label loop(this, 2, loop_vars), done_loop(this, &var_result); 1158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_value.Bind(value); 115962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNone)); 1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&loop); 1161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&loop); 1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Load the current {value}. 1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch value = var_value.value(); 1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if the {value} is a Smi or a HeapObject. 1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label if_valueissmi(this), if_valueisnotsmi(this); 1168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); 1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&if_valueissmi); 1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert the Smi {value}. 1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_result.Bind(SmiToWord32(value)); 1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_type_feedback->Bind( 117562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiOr(var_type_feedback->value(), 117662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiConstant(BinaryOperationFeedback::kSignedSmall))); 1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&done_loop); 1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&if_valueisnotsmi); 1181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if {value} is a HeapNumber. 1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label if_valueisheapnumber(this), 1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_valueisnotheapnumber(this, Label::kDeferred); 1185c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* value_map = LoadMap(value); 118662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Branch(IsHeapNumberMap(value_map), &if_valueisheapnumber, 118762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &if_valueisnotheapnumber); 1188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&if_valueisheapnumber); 1190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Truncate the floating point value. 1192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_result.Bind(TruncateHeapNumberValueToWord32(value)); 1193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch var_type_feedback->Bind( 119462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiOr(var_type_feedback->value(), 119562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiConstant(BinaryOperationFeedback::kNumber))); 1196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Goto(&done_loop); 1197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&if_valueisnotheapnumber); 1200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1201c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We do not require an Or with earlier feedback here because once we 1202c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // convert the value to a number, we cannot reach this path. We can 1203c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // only reach this path on the first pass when the feedback is kNone. 120462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CSA_ASSERT(this, SmiEqual(var_type_feedback->value(), 120562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiConstant(BinaryOperationFeedback::kNone))); 1206c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1207c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label if_valueisoddball(this), 1208c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if_valueisnotoddball(this, Label::kDeferred); 1209c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* is_oddball = Word32Equal(LoadMapInstanceType(value_map), 1210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Int32Constant(ODDBALL_TYPE)); 1211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(is_oddball, &if_valueisoddball, &if_valueisnotoddball); 1212c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1213c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&if_valueisoddball); 1214c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 1215c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Convert Oddball to a Number and perform checks again. 1216c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); 1217c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch var_type_feedback->Bind( 121862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); 1219c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&loop); 1220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1222c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bind(&if_valueisnotoddball); 1223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 1224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Convert the {value} to a Number first. 1225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch var_value.Bind(CallStub(callable, context, value)); 122762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kAny)); 1228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Goto(&loop); 1229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bind(&done_loop); 1234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return var_result.value(); 1235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InterpreterAssembler::UpdateInterruptBudgetOnReturn() { 1238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // TODO(rmcilroy): Investigate whether it is worth supporting self 1239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // optimization of primitive functions like FullCodegen. 1240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Update profiling count by -BytecodeOffset to simulate backedge to start of 1242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // function. 1243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* profiling_weight = 1244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), 124562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch TruncateWordToWord32(BytecodeOffset())); 124662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UpdateInterruptBudget(profiling_weight, false); 1247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1249bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::StackCheckTriggeredInterrupt() { 1250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* sp = LoadStackPointer(); 1251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stack_limit = Load( 1252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MachineType::Pointer(), 1253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); 1254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return UintPtrLessThan(sp, stack_limit); 1255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* InterpreterAssembler::LoadOSRNestingLevel() { 125862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return LoadObjectField(BytecodeArrayTaggedPointer(), 125962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BytecodeArray::kOSRNestingLevelOffset, 126062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType::Int8()); 1261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::Abort(BailoutReason bailout_reason) { 1264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch disable_stack_check_across_call_ = true; 1265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* abort_id = SmiTag(Int32Constant(bailout_reason)); 12663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CallRuntime(Runtime::kAbort, GetContext(), abort_id); 1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch disable_stack_check_across_call_ = false; 1268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, 1271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BailoutReason bailout_reason) { 1272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label ok(this), abort(this, Label::kDeferred); 1273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(WordEqual(lhs, rhs), &ok, &abort); 1274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&abort); 1276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Abort(bailout_reason); 1277bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&ok); 1278bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1279bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&ok); 1280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 128262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InterpreterAssembler::MaybeDropFrames(Node* context) { 128362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* restart_fp_address = 128462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalConstant(ExternalReference::debug_restart_fp_address(isolate())); 128562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 128662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* restart_fp = Load(MachineType::Pointer(), restart_fp_address); 128762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* null = IntPtrConstant(0); 128862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 128962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label ok(this), drop_frames(this); 129062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Branch(IntPtrEqual(restart_fp, null), &ok, &drop_frames); 129162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 129262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Bind(&drop_frames); 129362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We don't expect this call to return since the frame dropper tears down 129462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // the stack and jumps into the function on the target frame to restart it. 129562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallStub(CodeFactory::FrameDropperTrampoline(isolate()), context, restart_fp); 129662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Abort(kUnexpectedReturnFromFrameDropper); 129762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Goto(&ok); 129862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 129962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Bind(&ok); 130062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 130162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { 1303109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(), 13043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch SmiTag(BytecodeOffset()), GetAccumulatorUnchecked()); 1305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) { 1308bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* counters_table = ExternalConstant( 1309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ExternalReference::interpreter_dispatch_counters(isolate())); 1310bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* source_bytecode_table_index = IntPtrConstant( 1311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static_cast<int>(bytecode_) * (static_cast<int>(Bytecode::kLast) + 1)); 1312bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1313bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* counter_offset = 1314bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch WordShl(IntPtrAdd(source_bytecode_table_index, target_bytecode), 1315bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IntPtrConstant(kPointerSizeLog2)); 1316bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* old_counter = 1317bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Load(MachineType::IntPtr(), counters_table, counter_offset); 1318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1319bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label counter_ok(this), counter_saturated(this, Label::kDeferred); 1320bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1321bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* counter_reached_max = WordEqual( 1322bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch old_counter, IntPtrConstant(std::numeric_limits<uintptr_t>::max())); 1323c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Branch(counter_reached_max, &counter_saturated, &counter_ok); 1324bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1325bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&counter_ok); 1326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch { 1327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* new_counter = IntPtrAdd(old_counter, IntPtrConstant(1)); 1328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch StoreNoWriteBarrier(MachineType::PointerRepresentation(), counters_table, 1329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch counter_offset, new_counter); 1330bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&counter_saturated); 1331bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1332bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1333bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&counter_saturated); 1334bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1336109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static 1337109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool InterpreterAssembler::TargetSupportsUnalignedAccess() { 1338109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 1339109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 13403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 || \ 1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || \ 1342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch V8_TARGET_ARCH_PPC 1343109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return true; 1344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#else 1345109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#error "Unknown Architecture" 1346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif 1347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::RegisterCount() { 1350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* bytecode_array = LoadRegister(Register::bytecode_array()); 1351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* frame_size = LoadObjectField( 135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytecode_array, BytecodeArray::kFrameSizeOffset, MachineType::Uint32()); 135362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return WordShr(ChangeUint32ToWord(frame_size), 135462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IntPtrConstant(kPointerSizeLog2)); 1355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1357bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::ExportRegisterFile(Node* array) { 135862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* register_count = RegisterCount(); 1359bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_debug_code) { 1360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* array_size = LoadAndUntagFixedArrayBaseLength(array); 136162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AbortIfWordNotEqual(array_size, register_count, 136262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kInvalidRegisterFileInGenerator); 1363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 136562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Variable var_index(this, MachineType::PointerRepresentation()); 136662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_index.Bind(IntPtrConstant(0)); 1367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Iterate over register file and write values into array. 1369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The mapping of register to array index must match that used in 1370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // BytecodeGraphBuilder::VisitResumeGenerator. 1371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label loop(this, &var_index), done_loop(this); 1372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&loop); 1373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&loop); 1374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch { 1375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* index = var_index.value(); 137662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(UintPtrLessThan(index, register_count), &done_loop); 1377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 137862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* reg_index = IntPtrSub(IntPtrConstant(Register(0).ToOperand()), index); 137962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = LoadRegister(reg_index); 1380bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1381bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch StoreFixedArrayElement(array, index, value); 1382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 138362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_index.Bind(IntPtrAdd(index, IntPtrConstant(1))); 1384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&loop); 1385bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1386bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&done_loop); 1387bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return array; 1389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1390bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1391bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* InterpreterAssembler::ImportRegisterFile(Node* array) { 139262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* register_count = RegisterCount(); 1393bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_debug_code) { 1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* array_size = LoadAndUntagFixedArrayBaseLength(array); 139562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AbortIfWordNotEqual(array_size, register_count, 139662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kInvalidRegisterFileInGenerator); 1397bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 139962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Variable var_index(this, MachineType::PointerRepresentation()); 140062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_index.Bind(IntPtrConstant(0)); 1401bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1402bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Iterate over array and write values into register file. Also erase the 1403bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // array contents to not keep them alive artificially. 1404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Label loop(this, &var_index), done_loop(this); 1405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&loop); 1406bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&loop); 1407bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch { 1408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* index = var_index.value(); 140962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GotoIfNot(UintPtrLessThan(index, register_count), &done_loop); 1410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* value = LoadFixedArrayElement(array, index); 1412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 141362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* reg_index = IntPtrSub(IntPtrConstant(Register(0).ToOperand()), index); 141462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StoreRegister(value, reg_index); 1415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch StoreFixedArrayElement(array, index, StaleRegisterConstant()); 1417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 141862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch var_index.Bind(IntPtrAdd(index, IntPtrConstant(1))); 1419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Goto(&loop); 1420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Bind(&done_loop); 1422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1423bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return array; 1424bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1425bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace interpreter 1427109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace internal 1428109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace v8 1429