Index: vm/em/src/DrlProfileCollectionFramework.h =================================================================== --- vm/em/src/DrlProfileCollectionFramework.h (revision 618316) +++ vm/em/src/DrlProfileCollectionFramework.h (working copy) @@ -29,6 +29,7 @@ #include #include + class TbsEMClient; class ProfileCollector; class MethodProfile; @@ -37,6 +38,18 @@ typedef std::vector ProfileCollectors; typedef std::vector Jits; +// Profile collectors locking strategy for guarding non-critical data +enum PC_LOCKING_STRATEGY { + // No locks at all when possible + PC_LOCK_FREE=0, + + // Locking with conventional mutexes + PC_LOCK_MUTEX=1, + + // Locking with "occupied" flag + PC_LOCK_FLAG=2 +}; + class EM_PC_Interface { public: virtual ~EM_PC_Interface(){}; Index: vm/em/src/NValueProfileCollector.cpp =================================================================== --- vm/em/src/NValueProfileCollector.cpp (revision 618316) +++ vm/em/src/NValueProfileCollector.cpp (working copy) @@ -166,11 +166,17 @@ void TNVTableFirstNManager::addNewValue(ValueMethodProfile* methProfile, VPData* instProfile, ValueT curr_value) -{ - // TODO(egor): - // 1. options to enable/disable locking - // 2. flagged locking - methProfile->lockProfile(); +{ + // Decide what to do with locking + if (lockStrategy == PC_LOCK_FREE) { + // do nothing + } else if (lockStrategy == PC_LOCK_MUTEX) { + methProfile->lockProfile(); + } else if (lockStrategy == PC_LOCK_FLAG) { + if (isInUse) return; + isInUse = true; + } + ValueT* last_value = &(instProfile->last_value); uint32* num_times_profiled = &(instProfile->num_times_profiled); if (curr_value == *last_value){ @@ -183,7 +189,14 @@ insert(steady_part, clear_part, curr_value, *num_times_profiled); *last_value = curr_value; } - methProfile->unlockProfile(); + + if (lockStrategy == PC_LOCK_FREE) { + // do nothing + } else if (lockStrategy == PC_LOCK_MUTEX) { + methProfile->unlockProfile(); + } else if (lockStrategy == PC_LOCK_FLAG) { + isInUse = false; + } } //------------------------------------------------------------------------------ @@ -285,22 +298,22 @@ ValueProfileCollector::ValueProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, uint32 _TNV_steady_size, uint32 _TNV_clear_size, - uint32 _clear_interval, algotypes _TNV_algo_type) + uint32 _clear_interval, algotypes _TNV_algo_type, PC_LOCKING_STRATEGY lockStrategy) : ProfileCollector(em, name, EM_PCTYPE_VALUE, genJit) { hymutex_create(&profilesLock, TM_MUTEX_NESTED); if (_TNV_algo_type == TNV_DIVIDED) { tnvTableManager = new TNVTableDividedManager - (_TNV_steady_size, _TNV_clear_size, _clear_interval); + (_TNV_steady_size, _TNV_clear_size, _clear_interval, lockStrategy); }else if (_TNV_algo_type == TNV_FIRST_N) { tnvTableManager = new TNVTableFirstNManager - (_TNV_steady_size, _TNV_clear_size, _clear_interval); + (_TNV_steady_size, _TNV_clear_size, _clear_interval, lockStrategy); } catName = std::string(LOG_DOMAIN) + ".profiler." + name; loggingEnabled = is_info_enabled(LOG_DOMAIN) || is_info_enabled(catName.c_str()); if (loggingEnabled) { std::ostringstream msg; - msg<< "EM: value profiler intialized: "<jit, vpSteadySize, vpClearSize, vpClearInterval, vpMode); + std::string lockStrategyStr = getParam(config, profilerName+".lockStrategy"); + if (lockStrategyStr == "FREE") { + lockStrategy = PC_LOCK_FREE; + } else if (lockStrategyStr == "FLAG") { + lockStrategy = PC_LOCK_FLAG; + } else if (lockStrategyStr == "MUTEX") { + lockStrategy = PC_LOCK_MUTEX; + } else { + LECHO(9, "EM: illegal '{0}' value, defaulting to MUTEX" << "lockStrategy") + lockStrategy = PC_LOCK_MUTEX; + } + + pc = new ValueProfileCollector(this, profilerName, step->jit, vpSteadySize, vpClearSize, vpClearInterval, vpMode, lockStrategy); } return pc; } Index: vm/em/src/NValueProfileCollector.h =================================================================== --- vm/em/src/NValueProfileCollector.h (revision 618316) +++ vm/em/src/NValueProfileCollector.h (working copy) @@ -48,10 +48,12 @@ typedef POINTER_SIZE_INT ValueT; typedef VPInstructionProfileData VPData; TNVTableManager(uint32 steady_size, uint32 clear_size, - uint32 clear_interval) : + uint32 clear_interval, PC_LOCKING_STRATEGY lock_strategy) : steadySize(steady_size), clearSize(clear_size), - clearInterval(clear_interval) + clearInterval(clear_interval), + lockStrategy(lock_strategy), + isInUse(false) {} VPInstructionProfileData* createProfileData(); @@ -83,14 +85,16 @@ ValueT value_to_insert, uint32 times_met) = 0; const uint32 steadySize, clearSize, clearInterval; + const PC_LOCKING_STRATEGY lockStrategy; + bool isInUse; }; class TNVTableDividedManager : public TNVTableManager { public: // c-tor TNVTableDividedManager(uint32 steady_size, uint32 clear_size, - uint32 clear_interval) : - TNVTableManager(steady_size, clear_size, clear_interval) + uint32 clear_interval, PC_LOCKING_STRATEGY lock_strategy) : + TNVTableManager(steady_size, clear_size, clear_interval, lock_strategy) {} virtual void addNewValue(ValueMethodProfile* methProfile, @@ -105,8 +109,8 @@ public: // c-tor TNVTableFirstNManager(uint32 steady_size, uint32 clear_size, - uint32 clear_interval) : - TNVTableManager(steady_size, clear_size, clear_interval) + uint32 clear_interval, PC_LOCKING_STRATEGY lock_strategy) : + TNVTableManager(steady_size, clear_size, clear_interval, lock_strategy) {} virtual void addNewValue(ValueMethodProfile* methProfile, @@ -124,13 +128,13 @@ ValueProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, uint32 _TNV_steady_size, uint32 _TNV_clear_size, - uint32 _clear_interval, algotypes _TNV_algo_type); + uint32 _clear_interval, algotypes _TNV_algo_type, PC_LOCKING_STRATEGY lock_strategy); virtual TbsEMClient* getTbsEmClient() const {return (NULL);} virtual ~ValueProfileCollector(); MethodProfile* getMethodProfile(Method_Handle mh) const ; ValueMethodProfile* createProfile(Method_Handle mh, uint32 numkeys, uint32 keys[]); - + TNVTableManager* getTnvMgr() { return tnvTableManager; } private: std::string catName;