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

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

Issue 2709533002: Revert of [interpreter] Create custom call opcodes for specific argument counts (Closed)
Patch Set: 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>
8 #include <fstream> 7 #include <fstream>
9 #include <memory> 8 #include <memory>
10 9
11 #include "src/ast/prettyprinter.h" 10 #include "src/ast/prettyprinter.h"
12 #include "src/builtins/builtins-arguments.h" 11 #include "src/builtins/builtins-arguments.h"
13 #include "src/builtins/builtins-constructor.h" 12 #include "src/builtins/builtins-constructor.h"
14 #include "src/builtins/builtins-object.h" 13 #include "src/builtins/builtins-object.h"
15 #include "src/code-factory.h" 14 #include "src/code-factory.h"
16 #include "src/compilation-info.h" 15 #include "src/compilation-info.h"
17 #include "src/compiler.h" 16 #include "src/compiler.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) { 122 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) {
124 if (dispatch_table_[index] == nullptr) { 123 if (dispatch_table_[index] == nullptr) {
125 dispatch_table_[index] = dispatch_table_[illegal_index]; 124 dispatch_table_[index] = dispatch_table_[illegal_index];
126 } 125 }
127 } 126 }
128 127
129 // Initialization should have been successful. 128 // Initialization should have been successful.
130 DCHECK(IsDispatchTableInitialized()); 129 DCHECK(IsDispatchTableInitialized());
131 } 130 }
132 131
133 bool Interpreter::ReuseExistingHandler(Bytecode bytecode,
134 OperandScale operand_scale) {
135 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
136 switch (bytecode) {
137 case Bytecode::kCallProperty:
138 case Bytecode::kCallProperty0:
139 case Bytecode::kCallProperty1:
140 case Bytecode::kCallProperty2: {
141 const int offset = static_cast<int>(Bytecode::kCallProperty) -
142 static_cast<int>(Bytecode::kCall);
143 STATIC_ASSERT(offset ==
144 static_cast<int>(Bytecode::kCallProperty0) -
145 static_cast<int>(Bytecode::kCall0));
146 STATIC_ASSERT(offset ==
147 static_cast<int>(Bytecode::kCallProperty1) -
148 static_cast<int>(Bytecode::kCall1));
149 STATIC_ASSERT(offset ==
150 static_cast<int>(Bytecode::kCallProperty2) -
151 static_cast<int>(Bytecode::kCall2));
152 CHECK_LT(offset, index);
153 dispatch_table_[index] = dispatch_table_[index - offset];
154 return true;
155 break;
156 }
157 default:
158 return false;
159 }
160 }
161
162 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode, 132 void Interpreter::InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
163 OperandScale operand_scale, 133 OperandScale operand_scale,
164 BytecodeGeneratorFunc generator) { 134 BytecodeGeneratorFunc generator) {
165 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return; 135 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
166 if (ReuseExistingHandler(bytecode, operand_scale)) return;
167 136
168 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
169 InterpreterDispatchDescriptor descriptor(isolate_); 137 InterpreterDispatchDescriptor descriptor(isolate_);
170 compiler::CodeAssemblerState state( 138 compiler::CodeAssemblerState state(
171 isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER), 139 isolate_, zone, descriptor, Code::ComputeFlags(Code::BYTECODE_HANDLER),
172 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode)); 140 Bytecodes::ToString(bytecode), Bytecodes::ReturnCount(bytecode));
173 InterpreterAssembler assembler(&state, bytecode, operand_scale); 141 InterpreterAssembler assembler(&state, bytecode, operand_scale);
174 if (Bytecodes::MakesCallAlongCriticalPath(bytecode)) { 142 if (Bytecodes::MakesCallAlongCriticalPath(bytecode)) {
175 assembler.SaveBytecodeOffset(); 143 assembler.SaveBytecodeOffset();
176 } 144 }
177 (this->*generator)(&assembler); 145 (this->*generator)(&assembler);
178 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state); 146 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
147 size_t index = GetDispatchTableIndex(bytecode, operand_scale);
179 dispatch_table_[index] = code->entry(); 148 dispatch_table_[index] = code->entry();
180 TraceCodegen(code); 149 TraceCodegen(code);
181 PROFILE(isolate_, CodeCreateEvent( 150 PROFILE(isolate_, CodeCreateEvent(
182 CodeEventListener::BYTECODE_HANDLER_TAG, 151 CodeEventListener::BYTECODE_HANDLER_TAG,
183 AbstractCode::cast(*code), 152 AbstractCode::cast(*code),
184 Bytecodes::ToString(bytecode, operand_scale).c_str())); 153 Bytecodes::ToString(bytecode, operand_scale).c_str()));
185 } 154 }
186 155
187 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, 156 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
188 OperandScale operand_scale) { 157 OperandScale operand_scale) {
(...skipping 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 Node* slot_id = __ BytecodeOperandIdx(3); 2154 Node* slot_id = __ BytecodeOperandIdx(3);
2186 Node* feedback_vector = __ LoadFeedbackVector(); 2155 Node* feedback_vector = __ LoadFeedbackVector();
2187 Node* context = __ GetContext(); 2156 Node* context = __ GetContext();
2188 Node* result = 2157 Node* result =
2189 __ CallJSWithFeedback(function, context, receiver_arg, args_count, 2158 __ CallJSWithFeedback(function, context, receiver_arg, args_count,
2190 slot_id, feedback_vector, tail_call_mode); 2159 slot_id, feedback_vector, tail_call_mode);
2191 __ SetAccumulator(result); 2160 __ SetAccumulator(result);
2192 __ Dispatch(); 2161 __ Dispatch();
2193 } 2162 }
2194 2163
2195 void Interpreter::DoJSCallN(InterpreterAssembler* assembler, int arg_count) {
2196 const int kReceiverOperandIndex = 1;
2197 const int kReceiverOperandCount = 1;
2198 const int kSlotOperandIndex =
2199 kReceiverOperandIndex + kReceiverOperandCount + arg_count;
2200 const int kBoilerplatParameterCount = 7;
2201 const int kReceiverParameterIndex = 5;
2202
2203 Node* function_reg = __ BytecodeOperandReg(0);
2204 Node* function = __ LoadRegister(function_reg);
2205 std::array<Node*, Bytecodes::kMaxOperands + kBoilerplatParameterCount> temp;
2206 Callable call_ic = CodeFactory::CallIC(isolate_);
2207 temp[0] = __ HeapConstant(call_ic.code());
2208 temp[1] = function;
2209 temp[2] = __ Int32Constant(arg_count);
2210 temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex);
2211 temp[4] = __ LoadFeedbackVector();
2212 for (int i = 0; i < (arg_count + kReceiverOperandCount); ++i) {
2213 Node* reg = __ BytecodeOperandReg(i + kReceiverOperandIndex);
2214 temp[kReceiverParameterIndex + i] = __ LoadRegister(reg);
2215 }
2216 temp[kReceiverParameterIndex + arg_count + kReceiverOperandCount] =
2217 __ GetContext();
2218 Node* result = __ CallStubN(call_ic.descriptor(), 1,
2219 arg_count + kBoilerplatParameterCount, &temp[0]);
2220 __ SetAccumulator(result);
2221 __ Dispatch();
2222 }
2223
2224 // Call <callable> <receiver> <arg_count> <feedback_slot_id> 2164 // Call <callable> <receiver> <arg_count> <feedback_slot_id>
2225 // 2165 //
2226 // Call a JSfunction or Callable in |callable| with the |receiver| and 2166 // Call a JSfunction or Callable in |callable| with the |receiver| and
2227 // |arg_count| arguments in subsequent registers. Collect type feedback 2167 // |arg_count| arguments in subsequent registers. Collect type feedback
2228 // into |feedback_slot_id| 2168 // into |feedback_slot_id|
2229 void Interpreter::DoCall(InterpreterAssembler* assembler) { 2169 void Interpreter::DoCall(InterpreterAssembler* assembler) {
2230 DoJSCall(assembler, TailCallMode::kDisallow); 2170 DoJSCall(assembler, TailCallMode::kDisallow);
2231 } 2171 }
2232 2172
2233 void Interpreter::DoCall0(InterpreterAssembler* assembler) { 2173 // CallProperty <callable> <receiver> <arg_count> <feedback_slot_id>
2234 DoJSCallN(assembler, 0); 2174 //
2235 } 2175 // Call a JSfunction or Callable in |callable| with the |receiver| and
2236 2176 // |arg_count| arguments in subsequent registers. Collect type feedback into
2237 void Interpreter::DoCall1(InterpreterAssembler* assembler) { 2177 // |feedback_slot_id|. The callable is known to be a property of the receiver.
2238 DoJSCallN(assembler, 1);
2239 }
2240
2241 void Interpreter::DoCall2(InterpreterAssembler* assembler) {
2242 DoJSCallN(assembler, 2);
2243 }
2244
2245 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) { 2178 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) {
2246 // Same as Call 2179 // TODO(leszeks): Look into making the interpreter use the fact that the
2247 UNREACHABLE(); 2180 // receiver is non-null.
2248 } 2181 DoJSCall(assembler, TailCallMode::kDisallow);
2249
2250 void Interpreter::DoCallProperty0(InterpreterAssembler* assembler) {
2251 // Same as Call0
2252 UNREACHABLE();
2253 }
2254
2255 void Interpreter::DoCallProperty1(InterpreterAssembler* assembler) {
2256 // Same as Call1
2257 UNREACHABLE();
2258 }
2259
2260 void Interpreter::DoCallProperty2(InterpreterAssembler* assembler) {
2261 // Same as Call2
2262 UNREACHABLE();
2263 } 2182 }
2264 2183
2265 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id> 2184 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
2266 // 2185 //
2267 // Tail call a JSfunction or Callable in |callable| with the |receiver| and 2186 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
2268 // |arg_count| arguments in subsequent registers. Collect type feedback 2187 // |arg_count| arguments in subsequent registers. Collect type feedback
2269 // into |feedback_slot_id| 2188 // into |feedback_slot_id|
2270 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { 2189 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
2271 DoJSCall(assembler, TailCallMode::kAllow); 2190 DoJSCall(assembler, TailCallMode::kAllow);
2272 } 2191 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2312 // <first_return + 1> 2231 // <first_return + 1>
2313 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { 2232 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
2314 // Call the runtime function. 2233 // Call the runtime function.
2315 Node* function_id = __ BytecodeOperandRuntimeId(0); 2234 Node* function_id = __ BytecodeOperandRuntimeId(0);
2316 Node* first_arg_reg = __ BytecodeOperandReg(1); 2235 Node* first_arg_reg = __ BytecodeOperandReg(1);
2317 Node* first_arg = __ RegisterLocation(first_arg_reg); 2236 Node* first_arg = __ RegisterLocation(first_arg_reg);
2318 Node* args_count = __ BytecodeOperandCount(2); 2237 Node* args_count = __ BytecodeOperandCount(2);
2319 Node* context = __ GetContext(); 2238 Node* context = __ GetContext();
2320 Node* result_pair = 2239 Node* result_pair =
2321 __ CallRuntimeN(function_id, context, first_arg, args_count, 2); 2240 __ CallRuntimeN(function_id, context, first_arg, args_count, 2);
2241
2322 // Store the results in <first_return> and <first_return + 1> 2242 // Store the results in <first_return> and <first_return + 1>
2323 Node* first_return_reg = __ BytecodeOperandReg(3); 2243 Node* first_return_reg = __ BytecodeOperandReg(3);
2324 Node* second_return_reg = __ NextRegister(first_return_reg); 2244 Node* second_return_reg = __ NextRegister(first_return_reg);
2325 Node* result0 = __ Projection(0, result_pair); 2245 Node* result0 = __ Projection(0, result_pair);
2326 Node* result1 = __ Projection(1, result_pair); 2246 Node* result1 = __ Projection(1, result_pair);
2327 __ StoreRegister(result0, first_return_reg); 2247 __ StoreRegister(result0, first_return_reg);
2328 __ StoreRegister(result1, second_return_reg); 2248 __ StoreRegister(result1, second_return_reg);
2329 __ Dispatch(); 2249 __ Dispatch();
2330 } 2250 }
2331 2251
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 3378 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
3459 __ SmiTag(new_state)); 3379 __ SmiTag(new_state));
3460 __ SetAccumulator(old_state); 3380 __ SetAccumulator(old_state);
3461 3381
3462 __ Dispatch(); 3382 __ Dispatch();
3463 } 3383 }
3464 3384
3465 } // namespace interpreter 3385 } // namespace interpreter
3466 } // namespace internal 3386 } // namespace internal
3467 } // namespace v8 3387 } // 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