Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: src/interpreter/interpreter.cc

Issue 2673833003: [interpreter] Create custom call opcodes for specific argument counts (Closed)
Patch Set: Rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/interpreter.h ('k') | src/interpreter/interpreter-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/interpreter.h" 5 #include "src/interpreter/interpreter.h"
6 6
7 #include <array>
7 #include <fstream> 8 #include <fstream>
8 #include <memory> 9 #include <memory>
9 10
10 #include "src/ast/prettyprinter.h" 11 #include "src/ast/prettyprinter.h"
11 #include "src/builtins/builtins-constructor.h" 12 #include "src/builtins/builtins-constructor.h"
12 #include "src/code-factory.h" 13 #include "src/code-factory.h"
13 #include "src/compilation-info.h" 14 #include "src/compilation-info.h"
14 #include "src/compiler.h" 15 #include "src/compiler.h"
15 #include "src/factory.h" 16 #include "src/factory.h"
16 #include "src/interpreter/bytecode-flags.h" 17 #include "src/interpreter/bytecode-flags.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 124
124 // Initialization should have been successful. 125 // Initialization should have been successful.
125 DCHECK(IsDispatchTableInitialized()); 126 DCHECK(IsDispatchTableInitialized());
126 } 127 }
127 128
128 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode, 129 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
129 OperandScale operand_scale, 130 OperandScale operand_scale,
130 BytecodeGeneratorFunc generator) { 131 BytecodeGeneratorFunc generator) {
131 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return; 132 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
132 133
133 InterpreterDispatchDescriptor descriptor(isolate_);
134 compiler::CodeAssemblerState state(
135 isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER),
136 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode));
137 InterpreterAssembler assembler(&state, bytecode, operand_scale);
138 (this->*generator)(&assembler);
139 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
140 size_t index = GetDispatchTableIndex(bytecode, operand_scale); 134 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
141 dispatch_table_[index] = code->entry(); 135 switch (bytecode) {
142 TraceCodegen(code); 136 case Bytecode::kCallProperty:
143 PROFILE(isolate_, CodeCreateEvent( 137 case Bytecode::kCallProperty0:
144 CodeEventListener::BYTECODE_HANDLER_TAG, 138 case Bytecode::kCallProperty1:
145 AbstractCode::cast(*code), 139 case Bytecode::kCallProperty2: {
146 Bytecodes::ToString(bytecode, operand_scale).c_str())); 140 const int offset = static_cast<int>(Bytecode::kCallProperty) -
141 static_cast<int>(Bytecode::kCall);
142 STATIC_ASSERT(offset ==
143 static_cast<int>(Bytecode::kCallProperty0) -
144 static_cast<int>(Bytecode::kCall0));
145 STATIC_ASSERT(offset ==
146 static_cast<int>(Bytecode::kCallProperty1) -
147 static_cast<int>(Bytecode::kCall1));
148 STATIC_ASSERT(offset ==
149 static_cast<int>(Bytecode::kCallProperty2) -
150 static_cast<int>(Bytecode::kCall2));
151 dispatch_table_[index] = dispatch_table_[index - offset];
152 break;
153 }
154
155 default: {
156 InterpreterDispatchDescriptor descriptor(isolate_);
157 compiler::CodeAssemblerState state(
158 isolate_, zone, descriptor,
159 Code::ComputeFlags(Code::BYTECODE_HANDLER),
160 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode));
161 InterpreterAssembler assembler(&state, bytecode, operand_scale);
162 (this->*generator)(&assembler);
163 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
164 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
165 dispatch_table_[index] = code->entry();
166 TraceCodegen(code);
167 PROFILE(isolate_,
168 CodeCreateEvent(
169 CodeEventListener::BYTECODE_HANDLER_TAG,
170 AbstractCode::cast(*code),
171 Bytecodes::ToString(bytecode, operand_scale).c_str()));
172 break;
173 }
174 }
147 } 175 }
148 176
149 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, 177 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
150 OperandScale operand_scale) { 178 OperandScale operand_scale) {
151 DCHECK(IsDispatchTableInitialized()); 179 DCHECK(IsDispatchTableInitialized());
152 DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale)); 180 DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
153 size_t index = GetDispatchTableIndex(bytecode, operand_scale); 181 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
154 Address code_entry = dispatch_table_[index]; 182 Address code_entry = dispatch_table_[index];
155 return Code::GetCodeFromTargetAddress(code_entry); 183 return Code::GetCodeFromTargetAddress(code_entry);
156 } 184 }
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 Node* slot_id = __ BytecodeOperandIdx(3); 2085 Node* slot_id = __ BytecodeOperandIdx(3);
2058 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 2086 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
2059 Node* context = __ GetContext(); 2087 Node* context = __ GetContext();
2060 Node* result = 2088 Node* result =
2061 __ CallJSWithFeedback(function, context, receiver_arg, args_count, 2089 __ CallJSWithFeedback(function, context, receiver_arg, args_count,
2062 slot_id, type_feedback_vector, tail_call_mode); 2090 slot_id, type_feedback_vector, tail_call_mode);
2063 __ SetAccumulator(result); 2091 __ SetAccumulator(result);
2064 __ Dispatch(); 2092 __ Dispatch();
2065 } 2093 }
2066 2094
2095 void Interpreter::DoJSCallN(InterpreterAssembler* assembler, int n) {
2096 const int kFunctionOperandCount = 1;
2097 const int kReceiverOperandCount = 1;
2098 const int kBoilerplatParameterCount = 7;
2099 const int kReceiveParameterOffset = 5;
2100 Node* function_reg = __ BytecodeOperandReg(0);
2101 Node* function = __ LoadRegister(function_reg);
2102 std::array<Node*, Bytecodes::kMaxOperands + kBoilerplatParameterCount> temp;
2103 for (int i = 0; i < (n + kReceiverOperandCount); ++i) {
2104 Node* reg = __ BytecodeOperandReg(i + kFunctionOperandCount);
2105 temp[i + kReceiveParameterOffset] = __ LoadRegister(reg);
2106 }
2107 Callable call_ic = CodeFactory::CallIC(isolate_);
2108 temp[0] = __ HeapConstant(call_ic.code());
2109 temp[1] = function;
2110 temp[2] = __ Int32Constant(n);
2111 temp[3] = __ BytecodeOperandIdxInt32(n + kFunctionOperandCount +
2112 kReceiverOperandCount);
2113 temp[4] = __ LoadTypeFeedbackVector();
2114 temp[n + 6] = __ GetContext();
2115 Node* result = __ CallStubN(call_ic.descriptor(), 1,
2116 n + kBoilerplatParameterCount, &temp[0]);
2117 __ SetAccumulator(result);
2118 __ Dispatch();
2119 }
2120
2067 // Call <callable> <receiver> <arg_count> <feedback_slot_id> 2121 // Call <callable> <receiver> <arg_count> <feedback_slot_id>
2068 // 2122 //
2069 // Call a JSfunction or Callable in |callable| with the |receiver| and 2123 // Call a JSfunction or Callable in |callable| with the |receiver| and
2070 // |arg_count| arguments in subsequent registers. Collect type feedback 2124 // |arg_count| arguments in subsequent registers. Collect type feedback
2071 // into |feedback_slot_id| 2125 // into |feedback_slot_id|
2072 void Interpreter::DoCall(InterpreterAssembler* assembler) { 2126 void Interpreter::DoCall(InterpreterAssembler* assembler) {
2073 DoJSCall(assembler, TailCallMode::kDisallow); 2127 DoJSCall(assembler, TailCallMode::kDisallow);
2074 } 2128 }
2075 2129
2076 // CallProperty <callable> <receiver> <arg_count> <feedback_slot_id> 2130 void Interpreter::DoCall0(InterpreterAssembler* assembler) {
2077 // 2131 DoJSCallN(assembler, 0);
2078 // Call a JSfunction or Callable in |callable| with the |receiver| and 2132 }
2079 // |arg_count| arguments in subsequent registers. Collect type feedback into 2133
2080 // |feedback_slot_id|. The callable is known to be a property of the receiver. 2134 void Interpreter::DoCall1(InterpreterAssembler* assembler) {
2135 DoJSCallN(assembler, 1);
2136 }
2137
2138 void Interpreter::DoCall2(InterpreterAssembler* assembler) {
2139 DoJSCallN(assembler, 2);
2140 }
2141
2081 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) { 2142 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) {
2082 // TODO(leszeks): Look into making the interpreter use the fact that the 2143 // Same as Call
2083 // receiver is non-null. 2144 UNREACHABLE();
2084 DoJSCall(assembler, TailCallMode::kDisallow); 2145 }
2146
2147 void Interpreter::DoCallProperty0(InterpreterAssembler* assembler) {
2148 // Same as Call0
2149 UNREACHABLE();
2150 }
2151
2152 void Interpreter::DoCallProperty1(InterpreterAssembler* assembler) {
2153 // Same as Call1
2154 UNREACHABLE();
2155 }
2156
2157 void Interpreter::DoCallProperty2(InterpreterAssembler* assembler) {
2158 // Same as Call2
2159 UNREACHABLE();
2085 } 2160 }
2086 2161
2087 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id> 2162 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
2088 // 2163 //
2089 // Tail call a JSfunction or Callable in |callable| with the |receiver| and 2164 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
2090 // |arg_count| arguments in subsequent registers. Collect type feedback 2165 // |arg_count| arguments in subsequent registers. Collect type feedback
2091 // into |feedback_slot_id| 2166 // into |feedback_slot_id|
2092 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { 2167 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
2093 DoJSCall(assembler, TailCallMode::kAllow); 2168 DoJSCall(assembler, TailCallMode::kAllow);
2094 } 2169 }
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
3311 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 3386 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
3312 __ SmiTag(new_state)); 3387 __ SmiTag(new_state));
3313 __ SetAccumulator(old_state); 3388 __ SetAccumulator(old_state);
3314 3389
3315 __ Dispatch(); 3390 __ Dispatch();
3316 } 3391 }
3317 3392
3318 } // namespace interpreter 3393 } // namespace interpreter
3319 } // namespace internal 3394 } // namespace internal
3320 } // namespace v8 3395 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter.h ('k') | src/interpreter/interpreter-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698