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