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_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
8 #include <iosfwd> | 8 #include <iosfwd> |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2331 pass_argument_count_(pass_argument_count), | 2331 pass_argument_count_(pass_argument_count), |
2332 has_stack_check_(has_stack_check) { | 2332 has_stack_check_(has_stack_check) { |
2333 SetOperandAt(0, function); | 2333 SetOperandAt(0, function); |
2334 } | 2334 } |
2335 | 2335 |
2336 bool pass_argument_count_; | 2336 bool pass_argument_count_; |
2337 bool has_stack_check_; | 2337 bool has_stack_check_; |
2338 }; | 2338 }; |
2339 | 2339 |
2340 | 2340 |
2341 enum CallMode { NORMAL_CALL, TAIL_CALL }; | |
2342 | |
2343 | |
2341 class HCallWithDescriptor FINAL : public HInstruction { | 2344 class HCallWithDescriptor FINAL : public HInstruction { |
2342 public: | 2345 public: |
2343 static HCallWithDescriptor* New(Zone* zone, HValue* context, HValue* target, | 2346 static HCallWithDescriptor* New(Zone* zone, HValue* context, HValue* target, |
2344 int argument_count, | 2347 int argument_count, |
2345 CallInterfaceDescriptor descriptor, | 2348 CallInterfaceDescriptor descriptor, |
2346 const Vector<HValue*>& operands) { | 2349 const Vector<HValue*>& operands, |
2350 CallMode call_mode = NORMAL_CALL) { | |
2347 DCHECK(operands.length() == descriptor.GetEnvironmentLength()); | 2351 DCHECK(operands.length() == descriptor.GetEnvironmentLength()); |
2348 HCallWithDescriptor* res = new (zone) | 2352 HCallWithDescriptor* res = new (zone) HCallWithDescriptor( |
2349 HCallWithDescriptor(target, argument_count, descriptor, operands, zone); | 2353 target, argument_count, descriptor, operands, call_mode, zone); |
2350 return res; | 2354 return res; |
2351 } | 2355 } |
2352 | 2356 |
2353 virtual int OperandCount() const FINAL OVERRIDE { | 2357 virtual int OperandCount() const FINAL OVERRIDE { |
2354 return values_.length(); | 2358 return values_.length(); |
2355 } | 2359 } |
2356 virtual HValue* OperandAt(int index) const FINAL OVERRIDE { | 2360 virtual HValue* OperandAt(int index) const FINAL OVERRIDE { |
2357 return values_[index]; | 2361 return values_[index]; |
2358 } | 2362 } |
2359 | 2363 |
2360 virtual Representation RequiredInputRepresentation( | 2364 virtual Representation RequiredInputRepresentation( |
2361 int index) FINAL OVERRIDE { | 2365 int index) FINAL OVERRIDE { |
2362 if (index == 0) { | 2366 if (index == 0) { |
2363 return Representation::Tagged(); | 2367 return Representation::Tagged(); |
2364 } else { | 2368 } else { |
2365 int par_index = index - 1; | 2369 int par_index = index - 1; |
2366 DCHECK(par_index < descriptor_.GetEnvironmentLength()); | 2370 DCHECK(par_index < descriptor_.GetEnvironmentLength()); |
2367 return descriptor_.GetParameterRepresentation(par_index); | 2371 return descriptor_.GetParameterRepresentation(par_index); |
2368 } | 2372 } |
2369 } | 2373 } |
2370 | 2374 |
2371 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor) | 2375 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor) |
2372 | 2376 |
2373 virtual HType CalculateInferredType() FINAL OVERRIDE { | 2377 virtual HType CalculateInferredType() FINAL OVERRIDE { |
2374 return HType::Tagged(); | 2378 return HType::Tagged(); |
2375 } | 2379 } |
2376 | 2380 |
2381 bool IsTailCall() const { return call_mode_ == TAIL_CALL; } | |
2382 | |
2377 virtual int argument_count() const { | 2383 virtual int argument_count() const { |
2378 return argument_count_; | 2384 return argument_count_; |
2379 } | 2385 } |
2380 | 2386 |
2381 virtual int argument_delta() const OVERRIDE { | 2387 virtual int argument_delta() const OVERRIDE { |
2382 return -argument_count_; | 2388 return -argument_count_; |
2383 } | 2389 } |
2384 | 2390 |
2385 CallInterfaceDescriptor descriptor() const { return descriptor_; } | 2391 CallInterfaceDescriptor descriptor() const { return descriptor_; } |
2386 | 2392 |
2387 HValue* target() { | 2393 HValue* target() { |
2388 return OperandAt(0); | 2394 return OperandAt(0); |
2389 } | 2395 } |
2390 | 2396 |
2391 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT | 2397 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT |
2392 | 2398 |
2393 private: | 2399 private: |
2394 // The argument count includes the receiver. | 2400 // The argument count includes the receiver. |
2395 HCallWithDescriptor(HValue* target, int argument_count, | 2401 HCallWithDescriptor(HValue* target, int argument_count, |
2396 CallInterfaceDescriptor descriptor, | 2402 CallInterfaceDescriptor descriptor, |
2397 const Vector<HValue*>& operands, Zone* zone) | 2403 const Vector<HValue*>& operands, CallMode call_mode, |
2404 Zone* zone) | |
2398 : descriptor_(descriptor), | 2405 : descriptor_(descriptor), |
2399 values_(descriptor.GetEnvironmentLength() + 1, zone) { | 2406 values_(descriptor.GetEnvironmentLength() + 1, zone) { |
2407 // We can only tail call without any stack arguments. | |
2408 DCHECK(call_mode != TAIL_CALL || argument_count == 0); | |
2409 | |
2400 argument_count_ = argument_count; | 2410 argument_count_ = argument_count; |
2411 call_mode_ = call_mode; | |
Jakob Kummerow
2014/12/02 08:43:07
nit: for consistency, let's move both of these lin
mvstanton
2014/12/03 11:48:30
Done.
| |
2401 AddOperand(target, zone); | 2412 AddOperand(target, zone); |
2402 for (int i = 0; i < operands.length(); i++) { | 2413 for (int i = 0; i < operands.length(); i++) { |
2403 AddOperand(operands[i], zone); | 2414 AddOperand(operands[i], zone); |
2404 } | 2415 } |
2405 this->set_representation(Representation::Tagged()); | 2416 this->set_representation(Representation::Tagged()); |
2406 this->SetAllSideEffects(); | 2417 this->SetAllSideEffects(); |
2407 } | 2418 } |
2408 | 2419 |
2409 void AddOperand(HValue* v, Zone* zone) { | 2420 void AddOperand(HValue* v, Zone* zone) { |
2410 values_.Add(NULL, zone); | 2421 values_.Add(NULL, zone); |
2411 SetOperandAt(values_.length() - 1, v); | 2422 SetOperandAt(values_.length() - 1, v); |
2412 } | 2423 } |
2413 | 2424 |
2414 void InternalSetOperandAt(int index, | 2425 void InternalSetOperandAt(int index, |
2415 HValue* value) FINAL OVERRIDE { | 2426 HValue* value) FINAL OVERRIDE { |
2416 values_[index] = value; | 2427 values_[index] = value; |
2417 } | 2428 } |
2418 | 2429 |
2419 CallInterfaceDescriptor descriptor_; | 2430 CallInterfaceDescriptor descriptor_; |
2420 ZoneList<HValue*> values_; | 2431 ZoneList<HValue*> values_; |
2421 int argument_count_; | 2432 int argument_count_; |
2433 CallMode call_mode_; | |
2422 }; | 2434 }; |
2423 | 2435 |
2424 | 2436 |
2425 class HInvokeFunction FINAL : public HBinaryCall { | 2437 class HInvokeFunction FINAL : public HBinaryCall { |
2426 public: | 2438 public: |
2427 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int); | 2439 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int); |
2428 | 2440 |
2429 HInvokeFunction(HValue* context, | 2441 HInvokeFunction(HValue* context, |
2430 HValue* function, | 2442 HValue* function, |
2431 Handle<JSFunction> known_function, | 2443 Handle<JSFunction> known_function, |
(...skipping 2967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5399 private: | 5411 private: |
5400 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) | 5412 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) |
5401 : HUnaryCall(context, argument_count), | 5413 : HUnaryCall(context, argument_count), |
5402 major_key_(major_key) { | 5414 major_key_(major_key) { |
5403 } | 5415 } |
5404 | 5416 |
5405 CodeStub::Major major_key_; | 5417 CodeStub::Major major_key_; |
5406 }; | 5418 }; |
5407 | 5419 |
5408 | 5420 |
5409 class HTailCallThroughMegamorphicCache FINAL : public HTemplateInstruction<3> { | 5421 class HTailCallThroughMegamorphicCache FINAL : public HInstruction { |
5410 public: | 5422 public: |
5411 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HTailCallThroughMegamorphicCache, | 5423 enum Flags { |
5412 HValue*, HValue*, Code::Flags); | 5424 NONE = 0, |
5425 CALLED_FROM_KEYED_LOAD = 1 << 0, | |
5426 PERFORM_MISS_ONLY = 1 << 1 | |
5427 }; | |
5428 | |
5429 static Flags ComputeFlags(bool called_from_keyed_load, | |
5430 bool perform_miss_only) { | |
5431 Flags flags = NONE; | |
5432 if (called_from_keyed_load) { | |
5433 flags = static_cast<Flags>(flags | CALLED_FROM_KEYED_LOAD); | |
5434 } | |
5435 if (perform_miss_only) { | |
5436 flags = static_cast<Flags>(flags | PERFORM_MISS_ONLY); | |
5437 } | |
5438 return flags; | |
5439 } | |
5440 | |
5441 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5( | |
5442 HTailCallThroughMegamorphicCache, HValue*, HValue*, HValue*, HValue*, | |
5443 HTailCallThroughMegamorphicCache::Flags); | |
5444 | |
5445 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HTailCallThroughMegamorphicCache, | |
5446 HValue*, HValue*); | |
5413 | 5447 |
5414 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { | 5448 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { |
5415 return Representation::Tagged(); | 5449 return Representation::Tagged(); |
5416 } | 5450 } |
5417 | 5451 |
5452 virtual int OperandCount() const FINAL OVERRIDE { | |
5453 return FLAG_vector_ics ? 5 : 3; | |
5454 } | |
5455 virtual HValue* OperandAt(int i) const FINAL OVERRIDE { return inputs_[i]; } | |
5456 | |
5418 HValue* context() const { return OperandAt(0); } | 5457 HValue* context() const { return OperandAt(0); } |
5419 HValue* receiver() const { return OperandAt(1); } | 5458 HValue* receiver() const { return OperandAt(1); } |
5420 HValue* name() const { return OperandAt(2); } | 5459 HValue* name() const { return OperandAt(2); } |
5421 Code::Flags flags() const { return flags_; } | 5460 HValue* slot() const { |
5461 DCHECK(FLAG_vector_ics); | |
5462 return OperandAt(3); | |
5463 } | |
5464 HValue* vector() const { | |
5465 DCHECK(FLAG_vector_ics); | |
5466 return OperandAt(4); | |
5467 } | |
5468 Code::Flags flags() const; | |
5469 | |
5470 bool is_keyed_load() const { return flags_ & CALLED_FROM_KEYED_LOAD; } | |
5471 bool is_just_miss() const { return flags_ & PERFORM_MISS_ONLY; } | |
5422 | 5472 |
5423 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT | 5473 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT |
5424 | 5474 |
5425 DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache) | 5475 DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache) |
5426 | 5476 |
5477 protected: | |
5478 virtual void InternalSetOperandAt(int i, HValue* value) FINAL OVERRIDE { | |
5479 inputs_[i] = value; | |
5480 } | |
5481 | |
5427 private: | 5482 private: |
5428 HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver, | 5483 HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver, |
5429 HValue* name, Code::Flags flags) | 5484 HValue* name, HValue* slot, HValue* vector, |
5485 Flags flags) | |
5430 : flags_(flags) { | 5486 : flags_(flags) { |
5487 DCHECK(FLAG_vector_ics); | |
5488 SetOperandAt(0, context); | |
5489 SetOperandAt(1, receiver); | |
5490 SetOperandAt(2, name); | |
5491 SetOperandAt(3, slot); | |
5492 SetOperandAt(4, vector); | |
5493 } | |
5494 | |
5495 HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver, | |
5496 HValue* name) | |
5497 : flags_(NONE) { | |
5431 SetOperandAt(0, context); | 5498 SetOperandAt(0, context); |
5432 SetOperandAt(1, receiver); | 5499 SetOperandAt(1, receiver); |
5433 SetOperandAt(2, name); | 5500 SetOperandAt(2, name); |
5434 } | 5501 } |
5435 | 5502 |
5436 Code::Flags flags_; | 5503 EmbeddedContainer<HValue*, 5> inputs_; |
5504 Flags flags_; | |
5437 }; | 5505 }; |
5438 | 5506 |
5439 | 5507 |
5440 class HUnknownOSRValue FINAL : public HTemplateInstruction<0> { | 5508 class HUnknownOSRValue FINAL : public HTemplateInstruction<0> { |
5441 public: | 5509 public: |
5442 DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int); | 5510 DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int); |
5443 | 5511 |
5444 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT | 5512 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT |
5445 | 5513 |
5446 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { | 5514 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5519 | 5587 |
5520 class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> { | 5588 class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> { |
5521 public: | 5589 public: |
5522 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*, | 5590 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*, |
5523 Handle<String>, bool); | 5591 Handle<String>, bool); |
5524 | 5592 |
5525 HValue* context() { return OperandAt(0); } | 5593 HValue* context() { return OperandAt(0); } |
5526 HValue* global_object() { return OperandAt(1); } | 5594 HValue* global_object() { return OperandAt(1); } |
5527 Handle<String> name() const { return name_; } | 5595 Handle<String> name() const { return name_; } |
5528 bool for_typeof() const { return for_typeof_; } | 5596 bool for_typeof() const { return for_typeof_; } |
5529 FeedbackVectorICSlot slot() const { | 5597 FeedbackVectorICSlot slot() const { return slot_; } |
5530 DCHECK(FLAG_vector_ics && !slot_.IsInvalid()); | |
5531 return slot_; | |
5532 } | |
5533 Handle<TypeFeedbackVector> feedback_vector() const { | 5598 Handle<TypeFeedbackVector> feedback_vector() const { |
5534 return feedback_vector_; | 5599 return feedback_vector_; |
5535 } | 5600 } |
5601 bool HasVectorAndSlot() const { return FLAG_vector_ics; } | |
5536 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, | 5602 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, |
5537 FeedbackVectorICSlot slot) { | 5603 FeedbackVectorICSlot slot) { |
5538 DCHECK(FLAG_vector_ics); | 5604 DCHECK(FLAG_vector_ics); |
5539 feedback_vector_ = vector; | 5605 feedback_vector_ = vector; |
5540 slot_ = slot; | 5606 slot_ = slot; |
5541 } | 5607 } |
5542 | 5608 |
5543 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT | 5609 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT |
5544 | 5610 |
5545 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { | 5611 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6529 | 6595 |
6530 class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> { | 6596 class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> { |
6531 public: | 6597 public: |
6532 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadNamedGeneric, HValue*, | 6598 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadNamedGeneric, HValue*, |
6533 Handle<Object>); | 6599 Handle<Object>); |
6534 | 6600 |
6535 HValue* context() const { return OperandAt(0); } | 6601 HValue* context() const { return OperandAt(0); } |
6536 HValue* object() const { return OperandAt(1); } | 6602 HValue* object() const { return OperandAt(1); } |
6537 Handle<Object> name() const { return name_; } | 6603 Handle<Object> name() const { return name_; } |
6538 | 6604 |
6539 FeedbackVectorICSlot slot() const { | 6605 FeedbackVectorICSlot slot() const { return slot_; } |
6540 DCHECK(FLAG_vector_ics && !slot_.IsInvalid()); | |
6541 return slot_; | |
6542 } | |
6543 Handle<TypeFeedbackVector> feedback_vector() const { | 6606 Handle<TypeFeedbackVector> feedback_vector() const { |
6544 return feedback_vector_; | 6607 return feedback_vector_; |
6545 } | 6608 } |
6609 bool HasVectorAndSlot() const { return FLAG_vector_ics; } | |
6546 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, | 6610 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, |
6547 FeedbackVectorICSlot slot) { | 6611 FeedbackVectorICSlot slot) { |
6548 DCHECK(FLAG_vector_ics); | 6612 DCHECK(FLAG_vector_ics); |
6549 feedback_vector_ = vector; | 6613 feedback_vector_ = vector; |
6550 slot_ = slot; | 6614 slot_ = slot; |
6551 } | 6615 } |
6552 | 6616 |
6553 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { | 6617 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { |
6554 return Representation::Tagged(); | 6618 return Representation::Tagged(); |
6555 } | 6619 } |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6810 }; | 6874 }; |
6811 | 6875 |
6812 | 6876 |
6813 class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> { | 6877 class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> { |
6814 public: | 6878 public: |
6815 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadKeyedGeneric, HValue*, | 6879 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadKeyedGeneric, HValue*, |
6816 HValue*); | 6880 HValue*); |
6817 HValue* object() const { return OperandAt(0); } | 6881 HValue* object() const { return OperandAt(0); } |
6818 HValue* key() const { return OperandAt(1); } | 6882 HValue* key() const { return OperandAt(1); } |
6819 HValue* context() const { return OperandAt(2); } | 6883 HValue* context() const { return OperandAt(2); } |
6820 FeedbackVectorICSlot slot() const { | 6884 FeedbackVectorICSlot slot() const { return slot_; } |
6821 DCHECK(FLAG_vector_ics && !slot_.IsInvalid()); | |
6822 return slot_; | |
6823 } | |
6824 Handle<TypeFeedbackVector> feedback_vector() const { | 6885 Handle<TypeFeedbackVector> feedback_vector() const { |
6825 return feedback_vector_; | 6886 return feedback_vector_; |
6826 } | 6887 } |
6888 bool HasVectorAndSlot() const { return FLAG_vector_ics; } | |
6827 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, | 6889 void SetVectorAndSlot(Handle<TypeFeedbackVector> vector, |
6828 FeedbackVectorICSlot slot) { | 6890 FeedbackVectorICSlot slot) { |
6829 DCHECK(FLAG_vector_ics); | 6891 DCHECK(FLAG_vector_ics); |
6830 feedback_vector_ = vector; | 6892 feedback_vector_ = vector; |
6831 slot_ = slot; | 6893 slot_ = slot; |
6832 } | 6894 } |
6833 | 6895 |
6834 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT | 6896 virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT |
6835 | 6897 |
6836 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { | 6898 virtual Representation RequiredInputRepresentation(int index) OVERRIDE { |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7979 }; | 8041 }; |
7980 | 8042 |
7981 | 8043 |
7982 | 8044 |
7983 #undef DECLARE_INSTRUCTION | 8045 #undef DECLARE_INSTRUCTION |
7984 #undef DECLARE_CONCRETE_INSTRUCTION | 8046 #undef DECLARE_CONCRETE_INSTRUCTION |
7985 | 8047 |
7986 } } // namespace v8::internal | 8048 } } // namespace v8::internal |
7987 | 8049 |
7988 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 8050 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |