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

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

Issue 2684993002: [interpreter] Create custom call opcodes for specific argument counts (Closed)
Patch Set: Fix golden files again Created 3 years, 9 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-arguments.h" 12 #include "src/builtins/builtins-arguments.h"
12 #include "src/builtins/builtins-constructor.h" 13 #include "src/builtins/builtins-constructor.h"
13 #include "src/builtins/builtins-forin.h" 14 #include "src/builtins/builtins-forin.h"
14 #include "src/code-factory.h" 15 #include "src/code-factory.h"
15 #include "src/compilation-info.h" 16 #include "src/compilation-info.h"
16 #include "src/compiler.h" 17 #include "src/compiler.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) { 126 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) {
126 if (dispatch_table_[index] == nullptr) { 127 if (dispatch_table_[index] == nullptr) {
127 dispatch_table_[index] = dispatch_table_[illegal_index]; 128 dispatch_table_[index] = dispatch_table_[illegal_index];
128 } 129 }
129 } 130 }
130 131
131 // Initialization should have been successful. 132 // Initialization should have been successful.
132 DCHECK(IsDispatchTableInitialized()); 133 DCHECK(IsDispatchTableInitialized());
133 } 134 }
134 135
136 bool Interpreter::ReuseExistingHandler(Bytecode bytecode,
137 OperandScale operand_scale) {
138 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
139 switch (bytecode) {
140 case Bytecode::kCallProperty:
141 case Bytecode::kCallProperty0:
142 case Bytecode::kCallProperty1:
143 case Bytecode::kCallProperty2: {
144 const int offset = static_cast<int>(Bytecode::kCallProperty) -
145 static_cast<int>(Bytecode::kCall);
146 STATIC_ASSERT(offset ==
147 static_cast<int>(Bytecode::kCallProperty0) -
148 static_cast<int>(Bytecode::kCall0));
149 STATIC_ASSERT(offset ==
150 static_cast<int>(Bytecode::kCallProperty1) -
151 static_cast<int>(Bytecode::kCall1));
152 STATIC_ASSERT(offset ==
153 static_cast<int>(Bytecode::kCallProperty2) -
154 static_cast<int>(Bytecode::kCall2));
155 CHECK_LT(offset, index);
156 dispatch_table_[index] = dispatch_table_[index - offset];
157 return true;
158 break;
159 }
160 default:
161 return false;
162 }
163 }
164
135 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode, 165 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
136 OperandScale operand_scale, 166 OperandScale operand_scale,
137 BytecodeGeneratorFunc generator) { 167 BytecodeGeneratorFunc generator) {
138 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return; 168 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
169 if (ReuseExistingHandler(bytecode, operand_scale)) return;
139 170
171 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
140 InterpreterDispatchDescriptor descriptor(isolate_); 172 InterpreterDispatchDescriptor descriptor(isolate_);
141 compiler::CodeAssemblerState state( 173 compiler::CodeAssemblerState state(
142 isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER), 174 isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER),
143 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode)); 175 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode));
144 InterpreterAssembler assembler(&state, bytecode, operand_scale); 176 InterpreterAssembler assembler(&state, bytecode, operand_scale);
145 if (Bytecodes::MakesCallAlongCriticalPath(bytecode)) { 177 if (Bytecodes::MakesCallAlongCriticalPath(bytecode)) {
146 assembler.SaveBytecodeOffset(); 178 assembler.SaveBytecodeOffset();
147 } 179 }
148 (this->*generator)(&assembler); 180 (this->*generator)(&assembler);
149 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state); 181 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
150 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
151 dispatch_table_[index] = code->entry(); 182 dispatch_table_[index] = code->entry();
152 TraceCodegen(code); 183 TraceCodegen(code);
153 PROFILE(isolate_, CodeCreateEvent( 184 PROFILE(isolate_, CodeCreateEvent(
154 CodeEventListener::BYTECODE_HANDLER_TAG, 185 CodeEventListener::BYTECODE_HANDLER_TAG,
155 AbstractCode::cast(*code), 186 AbstractCode::cast(*code),
156 Bytecodes::ToString(bytecode, operand_scale).c_str())); 187 Bytecodes::ToString(bytecode, operand_scale).c_str()));
157 } 188 }
158 189
159 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, 190 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
160 OperandScale operand_scale) { 191 OperandScale operand_scale) {
(...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after
2182 Node* slot_id = __ BytecodeOperandIdx(3); 2213 Node* slot_id = __ BytecodeOperandIdx(3);
2183 Node* feedback_vector = __ LoadFeedbackVector(); 2214 Node* feedback_vector = __ LoadFeedbackVector();
2184 Node* context = __ GetContext(); 2215 Node* context = __ GetContext();
2185 Node* result = 2216 Node* result =
2186 __ CallJSWithFeedback(function, context, receiver_arg, args_count, 2217 __ CallJSWithFeedback(function, context, receiver_arg, args_count,
2187 slot_id, feedback_vector, tail_call_mode); 2218 slot_id, feedback_vector, tail_call_mode);
2188 __ SetAccumulator(result); 2219 __ SetAccumulator(result);
2189 __ Dispatch(); 2220 __ Dispatch();
2190 } 2221 }
2191 2222
2223 void Interpreter::DoJSCallN(InterpreterAssembler* assembler, int arg_count) {
2224 const int kReceiverOperandIndex = 1;
2225 const int kReceiverOperandCount = 1;
2226 const int kSlotOperandIndex =
2227 kReceiverOperandIndex + kReceiverOperandCount + arg_count;
2228 const int kBoilerplatParameterCount = 7;
2229 const int kReceiverParameterIndex = 5;
2230
2231 Node* function_reg = __ BytecodeOperandReg(0);
2232 Node* function = __ LoadRegister(function_reg);
2233 std::array<Node*, Bytecodes::kMaxOperands + kBoilerplatParameterCount> temp;
2234 Callable call_ic = CodeFactory::CallIC(isolate_);
2235 temp[0] = __ HeapConstant(call_ic.code());
2236 temp[1] = function;
2237 temp[2] = __ Int32Constant(arg_count);
2238 temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex);
2239 temp[4] = __ LoadFeedbackVector();
2240 for (int i = 0; i < (arg_count + kReceiverOperandCount); ++i) {
2241 Node* reg = __ BytecodeOperandReg(i + kReceiverOperandIndex);
2242 temp[kReceiverParameterIndex + i] = __ LoadRegister(reg);
2243 }
2244 temp[kReceiverParameterIndex + arg_count + kReceiverOperandCount] =
2245 __ GetContext();
2246 Node* result = __ CallStubN(call_ic.descriptor(), 1,
2247 arg_count + kBoilerplatParameterCount, &temp[0]);
2248 __ SetAccumulator(result);
2249 __ Dispatch();
2250 }
2251
2192 // Call <callable> <receiver> <arg_count> <feedback_slot_id> 2252 // Call <callable> <receiver> <arg_count> <feedback_slot_id>
2193 // 2253 //
2194 // Call a JSfunction or Callable in |callable| with the |receiver| and 2254 // Call a JSfunction or Callable in |callable| with the |receiver| and
2195 // |arg_count| arguments in subsequent registers. Collect type feedback 2255 // |arg_count| arguments in subsequent registers. Collect type feedback
2196 // into |feedback_slot_id| 2256 // into |feedback_slot_id|
2197 void Interpreter::DoCall(InterpreterAssembler* assembler) { 2257 void Interpreter::DoCall(InterpreterAssembler* assembler) {
2198 DoJSCall(assembler, TailCallMode::kDisallow); 2258 DoJSCall(assembler, TailCallMode::kDisallow);
2199 } 2259 }
2200 2260
2201 // CallProperty <callable> <receiver> <arg_count> <feedback_slot_id> 2261 void Interpreter::DoCall0(InterpreterAssembler* assembler) {
2202 // 2262 DoJSCallN(assembler, 0);
2203 // Call a JSfunction or Callable in |callable| with the |receiver| and 2263 }
2204 // |arg_count| arguments in subsequent registers. Collect type feedback into 2264
2205 // |feedback_slot_id|. The callable is known to be a property of the receiver. 2265 void Interpreter::DoCall1(InterpreterAssembler* assembler) {
2266 DoJSCallN(assembler, 1);
2267 }
2268
2269 void Interpreter::DoCall2(InterpreterAssembler* assembler) {
2270 DoJSCallN(assembler, 2);
2271 }
2272
2206 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) { 2273 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) {
2207 // TODO(leszeks): Look into making the interpreter use the fact that the 2274 // Same as Call
2208 // receiver is non-null. 2275 UNREACHABLE();
2209 DoJSCall(assembler, TailCallMode::kDisallow); 2276 }
2277
2278 void Interpreter::DoCallProperty0(InterpreterAssembler* assembler) {
2279 // Same as Call0
2280 UNREACHABLE();
2281 }
2282
2283 void Interpreter::DoCallProperty1(InterpreterAssembler* assembler) {
2284 // Same as Call1
2285 UNREACHABLE();
2286 }
2287
2288 void Interpreter::DoCallProperty2(InterpreterAssembler* assembler) {
2289 // Same as Call2
2290 UNREACHABLE();
2210 } 2291 }
2211 2292
2212 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id> 2293 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
2213 // 2294 //
2214 // Tail call a JSfunction or Callable in |callable| with the |receiver| and 2295 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
2215 // |arg_count| arguments in subsequent registers. Collect type feedback 2296 // |arg_count| arguments in subsequent registers. Collect type feedback
2216 // into |feedback_slot_id| 2297 // into |feedback_slot_id|
2217 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { 2298 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
2218 DoJSCall(assembler, TailCallMode::kAllow); 2299 DoJSCall(assembler, TailCallMode::kAllow);
2219 } 2300 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 // <first_return + 1> 2340 // <first_return + 1>
2260 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { 2341 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
2261 // Call the runtime function. 2342 // Call the runtime function.
2262 Node* function_id = __ BytecodeOperandRuntimeId(0); 2343 Node* function_id = __ BytecodeOperandRuntimeId(0);
2263 Node* first_arg_reg = __ BytecodeOperandReg(1); 2344 Node* first_arg_reg = __ BytecodeOperandReg(1);
2264 Node* first_arg = __ RegisterLocation(first_arg_reg); 2345 Node* first_arg = __ RegisterLocation(first_arg_reg);
2265 Node* args_count = __ BytecodeOperandCount(2); 2346 Node* args_count = __ BytecodeOperandCount(2);
2266 Node* context = __ GetContext(); 2347 Node* context = __ GetContext();
2267 Node* result_pair = 2348 Node* result_pair =
2268 __ CallRuntimeN(function_id, context, first_arg, args_count, 2); 2349 __ CallRuntimeN(function_id, context, first_arg, args_count, 2);
2269
2270 // Store the results in <first_return> and <first_return + 1> 2350 // Store the results in <first_return> and <first_return + 1>
2271 Node* first_return_reg = __ BytecodeOperandReg(3); 2351 Node* first_return_reg = __ BytecodeOperandReg(3);
2272 Node* second_return_reg = __ NextRegister(first_return_reg); 2352 Node* second_return_reg = __ NextRegister(first_return_reg);
2273 Node* result0 = __ Projection(0, result_pair); 2353 Node* result0 = __ Projection(0, result_pair);
2274 Node* result1 = __ Projection(1, result_pair); 2354 Node* result1 = __ Projection(1, result_pair);
2275 __ StoreRegister(result0, first_return_reg); 2355 __ StoreRegister(result0, first_return_reg);
2276 __ StoreRegister(result1, second_return_reg); 2356 __ StoreRegister(result1, second_return_reg);
2277 __ Dispatch(); 2357 __ Dispatch();
2278 } 2358 }
2279 2359
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3398 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 3478 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
3399 __ SmiTag(new_state)); 3479 __ SmiTag(new_state));
3400 __ SetAccumulator(old_state); 3480 __ SetAccumulator(old_state);
3401 3481
3402 __ Dispatch(); 3482 __ Dispatch();
3403 } 3483 }
3404 3484
3405 } // namespace interpreter 3485 } // namespace interpreter
3406 } // namespace internal 3486 } // namespace internal
3407 } // namespace v8 3487 } // 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