src/share/vm/oops/methodData.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/oops/methodData.hpp
src/share/vm/oops/methodData.hpp
Print this page
rev 5462 : 8026251: New type profiling points: parameters to methods
Summary: x86 interpreter and c1 type profiling for parameters on method entries
Reviewed-by:
*** 117,127 ****
ret_data_tag,
branch_data_tag,
multi_branch_data_tag,
arg_info_data_tag,
call_type_data_tag,
! virtual_call_type_data_tag
};
enum {
// The _struct._flags word is formatted as [trap_state:4 | flags:4].
// The trap state breaks down further as [recompile:1 | reason:3].
--- 117,128 ----
ret_data_tag,
branch_data_tag,
multi_branch_data_tag,
arg_info_data_tag,
call_type_data_tag,
! virtual_call_type_data_tag,
! parameters_type_data_tag
};
enum {
// The _struct._flags word is formatted as [trap_state:4 | flags:4].
// The trap state breaks down further as [recompile:1 | reason:3].
*** 262,271 ****
--- 263,273 ----
class JumpData;
class BranchData;
class ArrayData;
class MultiBranchData;
class ArgInfoData;
+ class ParametersTypeData;
// ProfileData
//
// A ProfileData object is created to refer to a section of profiling
// data in a structured way.
*** 395,404 ****
--- 397,407 ----
virtual bool is_ArrayData() const { return false; }
virtual bool is_MultiBranchData() const { return false; }
virtual bool is_ArgInfoData() const { return false; }
virtual bool is_CallTypeData() const { return false; }
virtual bool is_VirtualCallTypeData()const { return false; }
+ virtual bool is_ParametersTypeData() const { return false; }
BitData* as_BitData() const {
assert(is_BitData(), "wrong type");
return is_BitData() ? (BitData*) this : NULL;
*** 445,454 ****
--- 448,461 ----
}
VirtualCallTypeData* as_VirtualCallTypeData() const {
assert(is_VirtualCallTypeData(), "wrong type");
return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL;
}
+ ParametersTypeData* as_ParametersTypeData() const {
+ assert(is_ParametersTypeData(), "wrong type");
+ return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL;
+ }
// Subclass specific initialization
virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
*** 765,777 ****
public:
TypeStackSlotEntries(int base_off, int nb_entries)
: TypeEntries(base_off), _number_of_entries(nb_entries) {}
! static int compute_cell_count(Symbol* signature, int max);
! void post_initialize(Symbol* signature, bool has_receiver);
// offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
static int stack_slot_local_offset(int i) {
return i * per_arg_cell_count + stack_slot_entry;
}
--- 772,784 ----
public:
TypeStackSlotEntries(int base_off, int nb_entries)
: TypeEntries(base_off), _number_of_entries(nb_entries) {}
! static int compute_cell_count(Symbol* signature, bool include_receiver, int max);
! void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver);
// offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
static int stack_slot_local_offset(int i) {
return i * per_arg_cell_count + stack_slot_entry;
}
*** 944,964 ****
void check_number_of_arguments(int total) {
assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
}
- protected:
- // An entry for a return value takes less space than an entry for an
- // argument so if the number of cells exceeds the number of cells
- // needed for an argument, this object contains type information for
- // at least one argument.
- bool has_arguments() const {
- bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
- assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
- return res;
- }
-
public:
CallTypeData(DataLayout* layout) :
CounterData(layout),
_args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
_ret(cell_count() - ReturnTypeEntry::static_cell_count())
--- 951,960 ----
*** 1016,1025 ****
--- 1012,1031 ----
intptr_t current = _ret.type();
_ret.set_type(TypeEntries::with_status(k, current));
}
// An entry for a return value takes less space than an entry for an
+ // argument so if the number of cells exceeds the number of cells
+ // needed for an argument, this object contains type information for
+ // at least one argument.
+ bool has_arguments() const {
+ bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
+ assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
+ return res;
+ }
+
+ // An entry for a return value takes less space than an entry for an
// argument, so if the remainder of the number of cells divided by
// the number of cells for an argument is not null, a return value
// is profiled in this object.
bool has_return() const {
bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
*** 1211,1231 ****
void check_number_of_arguments(int total) {
assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
}
- protected:
- // An entry for a return value takes less space than an entry for an
- // argument so if the number of cells exceeds the number of cells
- // needed for an argument, this object contains type information for
- // at least one argument.
- bool has_arguments() const {
- bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
- assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
- return res;
- }
-
public:
VirtualCallTypeData(DataLayout* layout) :
VirtualCallData(layout),
_args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
_ret(cell_count() - ReturnTypeEntry::static_cell_count())
--- 1217,1226 ----
*** 1292,1301 ****
--- 1287,1306 ----
bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
return res;
}
+ // An entry for a return value takes less space than an entry for an
+ // argument so if the number of cells exceeds the number of cells
+ // needed for an argument, this object contains type information for
+ // at least one argument.
+ bool has_arguments() const {
+ bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
+ assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
+ return res;
+ }
+
// Code generation support
static ByteSize args_data_offset() {
return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
}
*** 1660,1669 ****
--- 1665,1743 ----
#ifndef PRODUCT
void print_data_on(outputStream* st) const;
#endif
};
+ // ParametersTypeData
+ //
+ // A ParametersTypeData is used to access profiling information about
+ // types of parameters to a method
+ class ParametersTypeData : public ArrayData {
+
+ private:
+ TypeStackSlotEntries _parameters;
+
+ static int stack_slot_local_offset(int i) {
+ assert_profiling_enabled();
+ return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i);
+ }
+
+ static int type_local_offset(int i) {
+ assert_profiling_enabled();
+ return array_start_off_set + TypeStackSlotEntries::type_local_offset(i);
+ }
+
+ static bool profiling_enabled();
+ static void assert_profiling_enabled() {
+ assert(profiling_enabled(), "method parameters profiling should be on");
+ }
+
+ public:
+ ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) {
+ assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type");
+ // Some compilers (VC++) don't want this passed in member initialization list
+ _parameters.set_profile_data(this);
+ }
+
+ static int compute_cell_count(Method* m);
+
+ virtual bool is_ParametersTypeData() const { return true; }
+
+ virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);
+
+ int number_of_parameters() const {
+ return array_len() / TypeStackSlotEntries::per_arg_count();
+ }
+
+ const TypeStackSlotEntries* parameters() const { return &_parameters; }
+
+ uint stack_slot(int i) const {
+ return _parameters.stack_slot(i);
+ }
+
+ void set_type(int i, Klass* k) {
+ intptr_t current = _parameters.type(i);
+ _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current));
+ }
+
+ virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
+ _parameters.clean_weak_klass_links(is_alive_closure);
+ }
+
+ #ifndef PRODUCT
+ virtual void print_data_on(outputStream* st) const;
+ #endif
+
+ static ByteSize stack_slot_offset(int i) {
+ return cell_offset(stack_slot_local_offset(i));
+ }
+
+ static ByteSize type_offset(int i) {
+ return cell_offset(type_local_offset(i));
+ }
+ };
+
// MethodData*
//
// A MethodData* holds information which has been collected about
// a method. Its layout looks like this:
//
*** 1771,1780 ****
--- 1845,1858 ----
bool _would_profile;
// Size of _data array in bytes. (Excludes header and extra_data fields.)
int _data_size;
+ // Offset with the MDO for the area dedicated to
+ // parameters. -1 if no parameter profiling.
+ int _parameters_type_data_di;
+
// Beginning of the data entries
intptr_t _data[1];
// Helper for size computation
static int compute_data_size(BytecodeStream* stream);
*** 1840,1849 ****
--- 1918,1930 ----
static bool profile_all_arguments();
static bool profile_arguments_for_invoke(methodHandle m, int bci);
static int profile_return_flag();
static bool profile_all_return();
static bool profile_return_for_invoke(methodHandle m, int bci);
+ static int profile_parameters_flag();
+ static bool profile_parameters_jsr292_only();
+ static bool profile_all_parameters();
public:
static int header_size() {
return sizeof(MethodData)/wordSize;
}
*** 2046,2055 ****
--- 2127,2146 ----
if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");
}
}
+ // Return pointer to area dedicated to parameters in MDO
+ ParametersTypeData* parameters_type_data() const {
+ return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL;
+ }
+
+ int parameters_type_data_di() const {
+ assert(_parameters_type_data_di != -1, "no args type data");
+ return _parameters_type_data_di;
+ }
+
// Support for code generation
static ByteSize data_offset() {
return byte_offset_of(MethodData, _data[0]);
}
*** 2058,2067 ****
--- 2149,2162 ----
}
static ByteSize backedge_counter_offset() {
return byte_offset_of(MethodData, _backedge_counter);
}
+ static ByteSize parameters_type_data_di_offset() {
+ return byte_offset_of(MethodData, _parameters_type_data_di);
+ }
+
// Deallocation support - no pointer fields to deallocate
void deallocate_contents(ClassLoaderData* loader_data) {}
// GC support
void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; }
*** 2081,2091 ****
--- 2176,2188 ----
// verification
void verify_on(outputStream* st);
void verify_data_on(outputStream* st);
+ static bool profile_parameters_for_method(methodHandle m);
static bool profile_arguments();
static bool profile_return();
+ static bool profile_parameters();
static bool profile_return_jsr292_only();
};
#endif // SHARE_VM_OOPS_METHODDATAOOP_HPP
src/share/vm/oops/methodData.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File