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