OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
8 #include <cstring> | 8 #include <cstring> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 | 10 |
(...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 | 2207 |
2208 Representation RequiredInputRepresentation(int index) final { | 2208 Representation RequiredInputRepresentation(int index) final { |
2209 return Representation::Tagged(); | 2209 return Representation::Tagged(); |
2210 } | 2210 } |
2211 | 2211 |
2212 HValue* first() const { return OperandAt(0); } | 2212 HValue* first() const { return OperandAt(0); } |
2213 HValue* second() const { return OperandAt(1); } | 2213 HValue* second() const { return OperandAt(1); } |
2214 }; | 2214 }; |
2215 | 2215 |
2216 | 2216 |
| 2217 enum CallMode { NORMAL_CALL, TAIL_CALL }; |
| 2218 |
| 2219 |
2217 class HCallWithDescriptor final : public HInstruction { | 2220 class HCallWithDescriptor final : public HInstruction { |
2218 public: | 2221 public: |
2219 static HCallWithDescriptor* New( | 2222 static HCallWithDescriptor* New(Isolate* isolate, Zone* zone, HValue* context, |
2220 Isolate* isolate, Zone* zone, HValue* context, HValue* target, | 2223 HValue* target, int argument_count, |
2221 int argument_count, CallInterfaceDescriptor descriptor, | 2224 CallInterfaceDescriptor descriptor, |
2222 const Vector<HValue*>& operands, | 2225 const Vector<HValue*>& operands, |
2223 TailCallMode syntactic_tail_call_mode = TailCallMode::kDisallow, | 2226 CallMode call_mode = NORMAL_CALL) { |
2224 TailCallMode tail_call_mode = TailCallMode::kDisallow) { | 2227 HCallWithDescriptor* res = new (zone) HCallWithDescriptor( |
2225 HCallWithDescriptor* res = new (zone) | 2228 target, argument_count, descriptor, operands, call_mode, zone); |
2226 HCallWithDescriptor(target, argument_count, descriptor, operands, | 2229 DCHECK_EQ(operands.length(), res->GetParameterCount()); |
2227 syntactic_tail_call_mode, tail_call_mode, zone); | |
2228 return res; | 2230 return res; |
2229 } | 2231 } |
2230 | 2232 |
2231 int OperandCount() const final { return values_.length(); } | 2233 int OperandCount() const final { return values_.length(); } |
2232 HValue* OperandAt(int index) const final { return values_[index]; } | 2234 HValue* OperandAt(int index) const final { return values_[index]; } |
2233 | 2235 |
2234 Representation RequiredInputRepresentation(int index) final { | 2236 Representation RequiredInputRepresentation(int index) final { |
2235 if (index == 0 || index == 1) { | 2237 if (index == 0 || index == 1) { |
2236 // Target + context | 2238 // Target + context |
2237 return Representation::Tagged(); | 2239 return Representation::Tagged(); |
2238 } else { | 2240 } else { |
2239 int par_index = index - 2; | 2241 int par_index = index - 2; |
2240 DCHECK(par_index < GetParameterCount()); | 2242 DCHECK(par_index < GetParameterCount()); |
2241 return RepresentationFromType(descriptor_.GetParameterType(par_index)); | 2243 return RepresentationFromType(descriptor_.GetParameterType(par_index)); |
2242 } | 2244 } |
2243 } | 2245 } |
2244 | 2246 |
2245 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor) | 2247 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor) |
2246 | 2248 |
2247 HType CalculateInferredType() final { return HType::Tagged(); } | 2249 HType CalculateInferredType() final { return HType::Tagged(); } |
2248 | 2250 |
2249 // Defines whether this instruction corresponds to a JS call at tail position. | 2251 bool IsTailCall() const { return call_mode_ == TAIL_CALL; } |
2250 TailCallMode syntactic_tail_call_mode() const { | |
2251 return SyntacticTailCallModeField::decode(bit_field_); | |
2252 } | |
2253 | |
2254 // Defines whether this call should be generated as a tail call. | |
2255 TailCallMode tail_call_mode() const { | |
2256 return TailCallModeField::decode(bit_field_); | |
2257 } | |
2258 bool IsTailCall() const { return tail_call_mode() == TailCallMode::kAllow; } | |
2259 | 2252 |
2260 virtual int argument_count() const { | 2253 virtual int argument_count() const { |
2261 return argument_count_; | 2254 return argument_count_; |
2262 } | 2255 } |
2263 | 2256 |
2264 int argument_delta() const override { return -argument_count_; } | 2257 int argument_delta() const override { return -argument_count_; } |
2265 | 2258 |
2266 CallInterfaceDescriptor descriptor() const { return descriptor_; } | 2259 CallInterfaceDescriptor descriptor() const { return descriptor_; } |
2267 | 2260 |
2268 HValue* target() { | 2261 HValue* target() { |
2269 return OperandAt(0); | 2262 return OperandAt(0); |
2270 } | 2263 } |
2271 | 2264 |
2272 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | 2265 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT |
2273 | 2266 |
2274 private: | 2267 private: |
2275 // The argument count includes the receiver. | 2268 // The argument count includes the receiver. |
2276 HCallWithDescriptor(HValue* target, int argument_count, | 2269 HCallWithDescriptor(HValue* target, int argument_count, |
2277 CallInterfaceDescriptor descriptor, | 2270 CallInterfaceDescriptor descriptor, |
2278 const Vector<HValue*>& operands, | 2271 const Vector<HValue*>& operands, CallMode call_mode, |
2279 TailCallMode syntactic_tail_call_mode, | 2272 Zone* zone) |
2280 TailCallMode tail_call_mode, Zone* zone) | |
2281 : descriptor_(descriptor), | 2273 : descriptor_(descriptor), |
2282 values_(GetParameterCount() + 1, zone), | 2274 values_(GetParameterCount() + 1, zone), |
2283 argument_count_(argument_count), | 2275 argument_count_(argument_count), |
2284 bit_field_( | 2276 call_mode_(call_mode) { |
2285 TailCallModeField::encode(tail_call_mode) | | |
2286 SyntacticTailCallModeField::encode(syntactic_tail_call_mode)) { | |
2287 DCHECK_EQ(operands.length(), GetParameterCount()); | |
2288 // We can only tail call without any stack arguments. | 2277 // We can only tail call without any stack arguments. |
2289 DCHECK(tail_call_mode != TailCallMode::kAllow || argument_count == 0); | 2278 DCHECK(call_mode != TAIL_CALL || argument_count == 0); |
2290 AddOperand(target, zone); | 2279 AddOperand(target, zone); |
2291 for (int i = 0; i < operands.length(); i++) { | 2280 for (int i = 0; i < operands.length(); i++) { |
2292 AddOperand(operands[i], zone); | 2281 AddOperand(operands[i], zone); |
2293 } | 2282 } |
2294 this->set_representation(Representation::Tagged()); | 2283 this->set_representation(Representation::Tagged()); |
2295 this->SetAllSideEffects(); | 2284 this->SetAllSideEffects(); |
2296 } | 2285 } |
2297 | 2286 |
2298 void AddOperand(HValue* v, Zone* zone) { | 2287 void AddOperand(HValue* v, Zone* zone) { |
2299 values_.Add(NULL, zone); | 2288 values_.Add(NULL, zone); |
2300 SetOperandAt(values_.length() - 1, v); | 2289 SetOperandAt(values_.length() - 1, v); |
2301 } | 2290 } |
2302 | 2291 |
2303 int GetParameterCount() const { | 2292 int GetParameterCount() const { |
2304 return descriptor_.GetRegisterParameterCount() + 1; | 2293 return descriptor_.GetRegisterParameterCount() + 1; |
2305 } | 2294 } |
2306 | 2295 |
2307 void InternalSetOperandAt(int index, HValue* value) final { | 2296 void InternalSetOperandAt(int index, HValue* value) final { |
2308 values_[index] = value; | 2297 values_[index] = value; |
2309 } | 2298 } |
2310 | 2299 |
2311 CallInterfaceDescriptor descriptor_; | 2300 CallInterfaceDescriptor descriptor_; |
2312 ZoneList<HValue*> values_; | 2301 ZoneList<HValue*> values_; |
2313 int argument_count_; | 2302 int argument_count_; |
2314 class TailCallModeField : public BitField<TailCallMode, 0, 1> {}; | 2303 CallMode call_mode_; |
2315 class SyntacticTailCallModeField | |
2316 : public BitField<TailCallMode, TailCallModeField::kNext, 1> {}; | |
2317 uint32_t bit_field_; | |
2318 }; | 2304 }; |
2319 | 2305 |
2320 | 2306 |
2321 class HInvokeFunction final : public HBinaryCall { | 2307 class HInvokeFunction final : public HBinaryCall { |
2322 public: | 2308 public: |
2323 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(HInvokeFunction, HValue*, | 2309 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HInvokeFunction, HValue*, |
2324 Handle<JSFunction>, int, | 2310 Handle<JSFunction>, int, |
2325 TailCallMode, TailCallMode); | 2311 TailCallMode); |
2326 | 2312 |
2327 HValue* context() { return first(); } | 2313 HValue* context() { return first(); } |
2328 HValue* function() { return second(); } | 2314 HValue* function() { return second(); } |
2329 Handle<JSFunction> known_function() { return known_function_; } | 2315 Handle<JSFunction> known_function() { return known_function_; } |
2330 int formal_parameter_count() const { return formal_parameter_count_; } | 2316 int formal_parameter_count() const { return formal_parameter_count_; } |
2331 | 2317 |
2332 bool HasStackCheck() final { return HasStackCheckField::decode(bit_field_); } | 2318 bool HasStackCheck() final { return HasStackCheckField::decode(bit_field_); } |
2333 | |
2334 // Defines whether this instruction corresponds to a JS call at tail position. | |
2335 TailCallMode syntactic_tail_call_mode() const { | |
2336 return SyntacticTailCallModeField::decode(bit_field_); | |
2337 } | |
2338 | |
2339 // Defines whether this call should be generated as a tail call. | |
2340 TailCallMode tail_call_mode() const { | 2319 TailCallMode tail_call_mode() const { |
2341 return TailCallModeField::decode(bit_field_); | 2320 return TailCallModeField::decode(bit_field_); |
2342 } | 2321 } |
2343 | 2322 |
2344 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) | 2323 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) |
2345 | 2324 |
2346 std::ostream& PrintTo(std::ostream& os) const override; // NOLINT | |
2347 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | |
2348 | |
2349 private: | 2325 private: |
2350 void set_has_stack_check(bool has_stack_check) { | 2326 void set_has_stack_check(bool has_stack_check) { |
2351 bit_field_ = HasStackCheckField::update(bit_field_, has_stack_check); | 2327 bit_field_ = HasStackCheckField::update(bit_field_, has_stack_check); |
2352 } | 2328 } |
2353 | 2329 |
2354 HInvokeFunction(HValue* context, HValue* function, | 2330 HInvokeFunction(HValue* context, HValue* function, |
2355 Handle<JSFunction> known_function, int argument_count, | 2331 Handle<JSFunction> known_function, int argument_count, |
2356 TailCallMode syntactic_tail_call_mode, | |
2357 TailCallMode tail_call_mode) | 2332 TailCallMode tail_call_mode) |
2358 : HBinaryCall(context, function, argument_count), | 2333 : HBinaryCall(context, function, argument_count), |
2359 known_function_(known_function), | 2334 known_function_(known_function), |
2360 bit_field_( | 2335 bit_field_(TailCallModeField::encode(tail_call_mode)) { |
2361 TailCallModeField::encode(tail_call_mode) | | |
2362 SyntacticTailCallModeField::encode(syntactic_tail_call_mode)) { | |
2363 DCHECK(tail_call_mode != TailCallMode::kAllow || | |
2364 syntactic_tail_call_mode == TailCallMode::kAllow); | |
2365 formal_parameter_count_ = | 2336 formal_parameter_count_ = |
2366 known_function.is_null() | 2337 known_function.is_null() |
2367 ? 0 | 2338 ? 0 |
2368 : known_function->shared()->internal_formal_parameter_count(); | 2339 : known_function->shared()->internal_formal_parameter_count(); |
2369 set_has_stack_check( | 2340 set_has_stack_check( |
2370 !known_function.is_null() && | 2341 !known_function.is_null() && |
2371 (known_function->code()->kind() == Code::FUNCTION || | 2342 (known_function->code()->kind() == Code::FUNCTION || |
2372 known_function->code()->kind() == Code::OPTIMIZED_FUNCTION)); | 2343 known_function->code()->kind() == Code::OPTIMIZED_FUNCTION)); |
2373 } | 2344 } |
2374 | 2345 |
2375 Handle<JSFunction> known_function_; | 2346 Handle<JSFunction> known_function_; |
2376 int formal_parameter_count_; | 2347 int formal_parameter_count_; |
2377 | 2348 |
2378 class HasStackCheckField : public BitField<bool, 0, 1> {}; | 2349 class HasStackCheckField : public BitField<bool, 0, 1> {}; |
2379 class TailCallModeField | 2350 class TailCallModeField |
2380 : public BitField<TailCallMode, HasStackCheckField::kNext, 1> {}; | 2351 : public BitField<TailCallMode, HasStackCheckField::kNext, 1> {}; |
2381 class SyntacticTailCallModeField | |
2382 : public BitField<TailCallMode, TailCallModeField::kNext, 1> {}; | |
2383 uint32_t bit_field_; | 2352 uint32_t bit_field_; |
2384 }; | 2353 }; |
2385 | 2354 |
2386 | 2355 |
2387 class HCallNewArray final : public HBinaryCall { | 2356 class HCallNewArray final : public HBinaryCall { |
2388 public: | 2357 public: |
2389 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, HValue*, int, | 2358 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, HValue*, int, |
2390 ElementsKind, | 2359 ElementsKind, |
2391 Handle<AllocationSite>); | 2360 Handle<AllocationSite>); |
2392 | 2361 |
(...skipping 5198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7591 | 7560 |
7592 | 7561 |
7593 | 7562 |
7594 #undef DECLARE_INSTRUCTION | 7563 #undef DECLARE_INSTRUCTION |
7595 #undef DECLARE_CONCRETE_INSTRUCTION | 7564 #undef DECLARE_CONCRETE_INSTRUCTION |
7596 | 7565 |
7597 } // namespace internal | 7566 } // namespace internal |
7598 } // namespace v8 | 7567 } // namespace v8 |
7599 | 7568 |
7600 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 7569 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |