Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_Instruction.hpp @ 12875:d13d7aba8c12
8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Wed, 09 Oct 2013 16:32:21 +0200 |
parents | 9758d9f36299 |
children | ce0cc25bc5e2 |
comparison
equal
deleted
inserted
replaced
12874:46ef27bcacb3 | 12875:d13d7aba8c12 |
---|---|
320 void set_type(ValueType* type) { | 320 void set_type(ValueType* type) { |
321 assert(type != NULL, "type must exist"); | 321 assert(type != NULL, "type must exist"); |
322 _type = type; | 322 _type = type; |
323 } | 323 } |
324 | 324 |
325 // Helper class to keep track of which arguments need a null check | |
326 class ArgsNonNullState { | |
327 private: | |
328 int _nonnull_state; // mask identifying which args are nonnull | |
329 public: | |
330 ArgsNonNullState() | |
331 : _nonnull_state(AllBits) {} | |
332 | |
333 // Does argument number i needs a null check? | |
334 bool arg_needs_null_check(int i) const { | |
335 // No data is kept for arguments starting at position 33 so | |
336 // conservatively assume that they need a null check. | |
337 if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { | |
338 return is_set_nth_bit(_nonnull_state, i); | |
339 } | |
340 return true; | |
341 } | |
342 | |
343 // Set whether argument number i needs a null check or not | |
344 void set_arg_needs_null_check(int i, bool check) { | |
345 if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { | |
346 if (check) { | |
347 _nonnull_state |= nth_bit(i); | |
348 } else { | |
349 _nonnull_state &= ~(nth_bit(i)); | |
350 } | |
351 } | |
352 } | |
353 }; | |
354 | |
325 public: | 355 public: |
326 void* operator new(size_t size) throw() { | 356 void* operator new(size_t size) throw() { |
327 Compilation* c = Compilation::current(); | 357 Compilation* c = Compilation::current(); |
328 void* res = c->arena()->Amalloc(size); | 358 void* res = c->arena()->Amalloc(size); |
329 ((Instruction*)res)->_id = c->get_next_id(); | 359 ((Instruction*)res)->_id = c->get_next_id(); |
564 virtual void input_values_do(ValueVisitor* f) = 0; | 594 virtual void input_values_do(ValueVisitor* f) = 0; |
565 virtual void state_values_do(ValueVisitor* f); | 595 virtual void state_values_do(ValueVisitor* f); |
566 virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ } | 596 virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ } |
567 void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); } | 597 void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); } |
568 | 598 |
569 virtual ciType* exact_type() const { return NULL; } | 599 virtual ciType* exact_type() const; |
570 virtual ciType* declared_type() const { return NULL; } | 600 virtual ciType* declared_type() const { return NULL; } |
571 | 601 |
572 // hashing | 602 // hashing |
573 virtual const char* name() const = 0; | 603 virtual const char* name() const = 0; |
574 HASHING1(Instruction, false, id()) // hashing disabled by default | 604 HASHING1(Instruction, false, id()) // hashing disabled by default |
687 | 717 |
688 // accessors | 718 // accessors |
689 int java_index() const { return _java_index; } | 719 int java_index() const { return _java_index; } |
690 | 720 |
691 virtual ciType* declared_type() const { return _declared_type; } | 721 virtual ciType* declared_type() const { return _declared_type; } |
692 virtual ciType* exact_type() const; | |
693 | 722 |
694 // generic | 723 // generic |
695 virtual void input_values_do(ValueVisitor* f) { /* no values */ } | 724 virtual void input_values_do(ValueVisitor* f) { /* no values */ } |
696 }; | 725 }; |
697 | 726 |
804 ValueStack* state_before, bool needs_patching) | 833 ValueStack* state_before, bool needs_patching) |
805 : AccessField(obj, offset, field, is_static, state_before, needs_patching) | 834 : AccessField(obj, offset, field, is_static, state_before, needs_patching) |
806 {} | 835 {} |
807 | 836 |
808 ciType* declared_type() const; | 837 ciType* declared_type() const; |
809 ciType* exact_type() const; | |
810 | 838 |
811 // generic | 839 // generic |
812 HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if needs patching or if volatile | 840 HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if needs patching or if volatile |
813 }; | 841 }; |
814 | 842 |
1297 // accessors | 1325 // accessors |
1298 Value length() const { return _length; } | 1326 Value length() const { return _length; } |
1299 | 1327 |
1300 virtual bool needs_exception_state() const { return false; } | 1328 virtual bool needs_exception_state() const { return false; } |
1301 | 1329 |
1330 ciType* exact_type() const { return NULL; } | |
1302 ciType* declared_type() const; | 1331 ciType* declared_type() const; |
1303 | 1332 |
1304 // generic | 1333 // generic |
1305 virtual bool can_trap() const { return true; } | 1334 virtual bool can_trap() const { return true; } |
1306 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_length); } | 1335 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_length); } |
1420 bool is_incompatible_class_change_check() const { | 1449 bool is_incompatible_class_change_check() const { |
1421 return check_flag(ThrowIncompatibleClassChangeErrorFlag); | 1450 return check_flag(ThrowIncompatibleClassChangeErrorFlag); |
1422 } | 1451 } |
1423 | 1452 |
1424 ciType* declared_type() const; | 1453 ciType* declared_type() const; |
1425 ciType* exact_type() const; | |
1426 }; | 1454 }; |
1427 | 1455 |
1428 | 1456 |
1429 LEAF(InstanceOf, TypeCheck) | 1457 LEAF(InstanceOf, TypeCheck) |
1430 public: | 1458 public: |
1488 LEAF(Intrinsic, StateSplit) | 1516 LEAF(Intrinsic, StateSplit) |
1489 private: | 1517 private: |
1490 vmIntrinsics::ID _id; | 1518 vmIntrinsics::ID _id; |
1491 Values* _args; | 1519 Values* _args; |
1492 Value _recv; | 1520 Value _recv; |
1493 int _nonnull_state; // mask identifying which args are nonnull | 1521 ArgsNonNullState _nonnull_state; |
1494 | 1522 |
1495 public: | 1523 public: |
1496 // preserves_state can be set to true for Intrinsics | 1524 // preserves_state can be set to true for Intrinsics |
1497 // which are guaranteed to preserve register state across any slow | 1525 // which are guaranteed to preserve register state across any slow |
1498 // cases; setting it to true does not mean that the Intrinsic can | 1526 // cases; setting it to true does not mean that the Intrinsic can |
1509 bool cantrap = true) | 1537 bool cantrap = true) |
1510 : StateSplit(type, state_before) | 1538 : StateSplit(type, state_before) |
1511 , _id(id) | 1539 , _id(id) |
1512 , _args(args) | 1540 , _args(args) |
1513 , _recv(NULL) | 1541 , _recv(NULL) |
1514 , _nonnull_state(AllBits) | |
1515 { | 1542 { |
1516 assert(args != NULL, "args must exist"); | 1543 assert(args != NULL, "args must exist"); |
1517 ASSERT_VALUES | 1544 ASSERT_VALUES |
1518 set_flag(PreservesStateFlag, preserves_state); | 1545 set_flag(PreservesStateFlag, preserves_state); |
1519 set_flag(CanTrapFlag, cantrap); | 1546 set_flag(CanTrapFlag, cantrap); |
1535 | 1562 |
1536 bool has_receiver() const { return (_recv != NULL); } | 1563 bool has_receiver() const { return (_recv != NULL); } |
1537 Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; } | 1564 Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; } |
1538 bool preserves_state() const { return check_flag(PreservesStateFlag); } | 1565 bool preserves_state() const { return check_flag(PreservesStateFlag); } |
1539 | 1566 |
1540 bool arg_needs_null_check(int i) { | 1567 bool arg_needs_null_check(int i) const { |
1541 if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { | 1568 return _nonnull_state.arg_needs_null_check(i); |
1542 return is_set_nth_bit(_nonnull_state, i); | |
1543 } | |
1544 return true; | |
1545 } | 1569 } |
1546 | 1570 |
1547 void set_arg_needs_null_check(int i, bool check) { | 1571 void set_arg_needs_null_check(int i, bool check) { |
1548 if (i >= 0 && i < (int)sizeof(_nonnull_state) * BitsPerByte) { | 1572 _nonnull_state.set_arg_needs_null_check(i, check); |
1549 if (check) { | |
1550 _nonnull_state |= nth_bit(i); | |
1551 } else { | |
1552 _nonnull_state &= ~(nth_bit(i)); | |
1553 } | |
1554 } | |
1555 } | 1573 } |
1556 | 1574 |
1557 // generic | 1575 // generic |
1558 virtual bool can_trap() const { return check_flag(CanTrapFlag); } | 1576 virtual bool can_trap() const { return check_flag(CanTrapFlag); } |
1559 virtual void input_values_do(ValueVisitor* f) { | 1577 virtual void input_values_do(ValueVisitor* f) { |
2448 } | 2466 } |
2449 }; | 2467 }; |
2450 | 2468 |
2451 LEAF(ProfileCall, Instruction) | 2469 LEAF(ProfileCall, Instruction) |
2452 private: | 2470 private: |
2453 ciMethod* _method; | 2471 ciMethod* _method; |
2454 int _bci_of_invoke; | 2472 int _bci_of_invoke; |
2455 ciMethod* _callee; // the method that is called at the given bci | 2473 ciMethod* _callee; // the method that is called at the given bci |
2456 Value _recv; | 2474 Value _recv; |
2457 ciKlass* _known_holder; | 2475 ciKlass* _known_holder; |
2458 | 2476 Values* _obj_args; // arguments for type profiling |
2459 public: | 2477 ArgsNonNullState _nonnull_state; // Do we know whether some arguments are never null? |
2460 ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder) | 2478 bool _inlined; // Are we profiling a call that is inlined |
2479 | |
2480 public: | |
2481 ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) | |
2461 : Instruction(voidType) | 2482 : Instruction(voidType) |
2462 , _method(method) | 2483 , _method(method) |
2463 , _bci_of_invoke(bci) | 2484 , _bci_of_invoke(bci) |
2464 , _callee(callee) | 2485 , _callee(callee) |
2465 , _recv(recv) | 2486 , _recv(recv) |
2466 , _known_holder(known_holder) | 2487 , _known_holder(known_holder) |
2488 , _obj_args(obj_args) | |
2489 , _inlined(inlined) | |
2467 { | 2490 { |
2468 // The ProfileCall has side-effects and must occur precisely where located | 2491 // The ProfileCall has side-effects and must occur precisely where located |
2469 pin(); | 2492 pin(); |
2470 } | 2493 } |
2471 | 2494 |
2472 ciMethod* method() { return _method; } | 2495 ciMethod* method() const { return _method; } |
2473 int bci_of_invoke() { return _bci_of_invoke; } | 2496 int bci_of_invoke() const { return _bci_of_invoke; } |
2474 ciMethod* callee() { return _callee; } | 2497 ciMethod* callee() const { return _callee; } |
2475 Value recv() { return _recv; } | 2498 Value recv() const { return _recv; } |
2476 ciKlass* known_holder() { return _known_holder; } | 2499 ciKlass* known_holder() const { return _known_holder; } |
2477 | 2500 int nb_profiled_args() const { return _obj_args == NULL ? 0 : _obj_args->length(); } |
2478 virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); } | 2501 Value profiled_arg_at(int i) const { return _obj_args->at(i); } |
2479 }; | 2502 bool arg_needs_null_check(int i) const { |
2480 | 2503 return _nonnull_state.arg_needs_null_check(i); |
2504 } | |
2505 bool inlined() const { return _inlined; } | |
2506 | |
2507 void set_arg_needs_null_check(int i, bool check) { | |
2508 _nonnull_state.set_arg_needs_null_check(i, check); | |
2509 } | |
2510 | |
2511 virtual void input_values_do(ValueVisitor* f) { | |
2512 if (_recv != NULL) { | |
2513 f->visit(&_recv); | |
2514 } | |
2515 for (int i = 0; i < nb_profiled_args(); i++) { | |
2516 f->visit(_obj_args->adr_at(i)); | |
2517 } | |
2518 } | |
2519 }; | |
2481 | 2520 |
2482 // Call some C runtime function that doesn't safepoint, | 2521 // Call some C runtime function that doesn't safepoint, |
2483 // optionally passing the current thread as the first argument. | 2522 // optionally passing the current thread as the first argument. |
2484 LEAF(RuntimeCall, Instruction) | 2523 LEAF(RuntimeCall, Instruction) |
2485 private: | 2524 private: |