Browse Source

initial stack calculation

+ clang 12.0.1, + stick to x86_64 arch.
Calculation may be suppressed by providing env values:

* MANTICORE_KNOWN_CREATE_SIZE
(for x86_64: clang 12.0.1 relwithdebinfo = 768, debug = 4208.
gcc 9.3 relwithdebinfo = 16, debug = 256)

* MANTICORE_KNOWN_EXPR_SIZE
(for x86_64: clang 12.0.1 relwithdebinfo = 32, debug = 48.
gcc 9.3 relwithdebinfo = 48, debug = 48)

* MANTICORE_KNOWN_FILTER_SIZE
(for x86_64: clang 12.0.1 relwithdebinfo = 208, debug = 400.
gcc 9.3 relwithdebinfo = 240, debug = 272)

If no value compiled in or provided via env, daemon probes stack on
startup and issue calculated value to the log with 'debug' level
alexey 4 years ago
parent
commit
37599b3e3c
3 changed files with 122 additions and 70 deletions
  1. 2 0
      misc/ctest/memcheck.cmake
  2. 16 6
      src/CMakeLists.txt
  3. 104 64
      src/stackmock.cpp

+ 2 - 0
misc/ctest/memcheck.cmake

@@ -22,6 +22,8 @@ if ( NOT CTEST_SOURCE_DIRECTORY )
 	set ( CTEST_SOURCE_DIRECTORY ".." )
 endif ()
 
+# just reference line for manual configuration
+# cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_ODBC=1 -DWITH_RE2=1 -DWITH_STEMMER=1 -DWITH_POSTGRESQL=0 -DWITH_EXPAT=1 -DWITH_SSL=1 -DTEST_SPECIAL_EXTERNAL=1 -DDISABLE_MEMROUTINES=1 -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 ..
 # common test options
 set ( CONFIG_OPTIONS "WITH_ODBC=1;WITH_RE2=1;WITH_STEMMER=1;WITH_POSTGRESQL=0;WITH_EXPAT=1;WITH_SSL=1;TEST_SPECIAL_EXTERNAL=1;DISABLE_MEMROUTINES=1" )
 set ( CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/build" )

+ 16 - 6
src/CMakeLists.txt

@@ -211,12 +211,22 @@ add_library ( digest_sha1 digest_sha1.cpp )
 target_link_libraries ( digest_sha1 PRIVATE lextra )
 target_link_libraries ( lsearchd PUBLIC digest_sha1 lextra )
 
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "12")
-	set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "KNOWN_CREATE_SIZE=768;KNOWN_EXPR_SIZE=32;KNOWN_FILTER_SIZE=208" )
-	set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_DEBUG "KNOWN_CREATE_SIZE=4208;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=400")
-elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "9.3")
-	set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "KNOWN_CREATE_SIZE=16;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=240" )
-	set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_DEBUG "KNOWN_CREATE_SIZE=256;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=272" )
+diag ( CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION )
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+	if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+#		if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "12")
+		if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "12.0.1" OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "12")
+			diags("Select precalculated values for Clang 12.0.X on x86_64" )
+			set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "KNOWN_CREATE_SIZE=768;KNOWN_EXPR_SIZE=32;KNOWN_FILTER_SIZE=208" )
+			set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_DEBUG "KNOWN_CREATE_SIZE=4208;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=400")
+		endif()
+	elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+		if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "9.3")
+			diags ( "Select precalculated values for GCC 9.3 on x86_64" )
+			set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "KNOWN_CREATE_SIZE=16;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=240" )
+			set_source_files_properties ( stackmock.cpp PROPERTIES COMPILE_DEFINITIONS_DEBUG "KNOWN_CREATE_SIZE=256;KNOWN_EXPR_SIZE=48;KNOWN_FILTER_SIZE=272" )
+		endif()
+	endif ()
 endif()
 
 if (WITH_ZLIB)

+ 104 - 64
src/stackmock.cpp

@@ -148,6 +148,10 @@ class CreateExprStackSize_c : public StackMeasurer_c
 
 protected:
 	StringBuilder_c m_sExpr;
+
+public:
+	static int MockMeasure();
+	static void PublishValue (int iStack);
 };
 
 // measure stack for evaluate expression
@@ -202,56 +206,11 @@ class EvalExprStackSize_c : public CreateExprStackSize_c
 		if ( !tParams.m_bSuccess || !tParams.m_sError.IsEmpty () )
 			sphWarning ( "stack check expression error: %s", tParams.m_sError.cstr () );
 	}
-};
-
-void DetermineNodeItemStackSize()
-{
-	int iCreateSize=0;
-	int iEvalSize=0;
 
-	bool bRunNatively = !Threads::IsUnderValgrind();
-	bool bNeedCheck = true;
-#ifdef KNOWN_CREATE_SIZE
-	iCreateSize = KNOWN_CREATE_SIZE;
-	bNeedCheck = bRunNatively;
-#endif
-
-	if ( bNeedCheck )
-	{
-		CreateExprStackSize_c tCreateMeter;
-		auto iNewCreateSize = tCreateMeter.MockMeasureStack ( 5 );
-
-#ifdef NDEBUG
-		if ( iCreateSize && iCreateSize < iNewCreateSize )
-			sphWarning ( "Compiled-in value KNOWN_CREATE_SIZE (%d) is less than measured (%d). Consider to fix the value!", iCreateSize, iNewCreateSize );
-#endif
-
-		iCreateSize = iNewCreateSize;
-	}
-	sphLogDebug ( "expression stack for creation %d", iCreateSize );
-
-	// save the metric, as next measuring eval metric with deeper recursion may already use the value
-	SetExprNodeStackItemSize ( iCreateSize, 0 );
-
-#ifdef KNOWN_EXPR_SIZE
-	iEvalSize = KNOWN_EXPR_SIZE;
-	bNeedCheck = bRunNatively;
-#endif
-	if ( bNeedCheck )
-	{
-		EvalExprStackSize_c tEvalMeter;
-		auto iNewEvalSize = tEvalMeter.MockMeasureStack ( 20 );
-
-#ifdef NDEBUG
-		if ( iEvalSize && iEvalSize < iNewEvalSize )
-			sphWarning ( "Compiled-in value KNOWN_EXPR_SIZE (%d) is less than measured (%d). Consider to fix the value!", iEvalSize, iNewEvalSize );
-#endif
-
-		iEvalSize = iNewEvalSize;
-	}
-	sphLogDebug ( "expression stack for eval/deletion %d", iEvalSize );
-	SetExprNodeStackItemSize ( 0, iEvalSize );
-}
+public:
+	static int MockMeasure();
+	static void PublishValue ( int iStack );
+};
 
 /////////////////////////////////////////////////////////////////////
 class FilterCreationMeasureStack_c : public StackMeasurer_c
@@ -307,27 +266,108 @@ class FilterCreationMeasureStack_c : public StackMeasurer_c
 
 protected:
 	StringBuilder_c m_sQuery;
+
+public:
+	static int MockMeasure();
+	static void PublishValue ( int iStack );
 };
 
-void DetermineFilterItemStackSize ()
+int CreateExprStackSize_c::MockMeasure()
 {
-	bool bNeedCheck = true;
-	int iDelta=0;
-#ifdef KNOWN_FILTER_SIZE
-	iDelta = KNOWN_FILTER_SIZE;
-	bNeedCheck = !Threads::IsUnderValgrind();
-#endif
-	if ( bNeedCheck )
+	CreateExprStackSize_c tCreateMeter;
+	return tCreateMeter.MockMeasureStack ( 5 );
+}
+
+int EvalExprStackSize_c::MockMeasure()
+{
+	EvalExprStackSize_c tEvalMeter;
+	return tEvalMeter.MockMeasureStack ( 20 );
+}
+
+int FilterCreationMeasureStack_c::MockMeasure()
+{
+	FilterCreationMeasureStack_c tCreateMeter;
+	return tCreateMeter.MockMeasureStack ( 100 );
+}
+
+void CreateExprStackSize_c::PublishValue ( int iStack )
+{
+	SetExprNodeStackItemSize ( iStack, 0 );
+}
+
+void EvalExprStackSize_c::PublishValue ( int iStack )
+{
+	SetExprNodeStackItemSize ( 0, iStack );
+}
+
+void FilterCreationMeasureStack_c::PublishValue ( int iStack )
+{
+	SetFilterStackItemSize ( iStack );
+}
+
+
+template<typename MOCK, int COMPILEDVAL>
+void DetermineStackSize ( const char* szReport, const char* szEnv )
+{
+	int iSize = COMPILEDVAL;
+	int iNewSize = 0;
+	bool bMocked = false;
+	if ( !( COMPILEDVAL && Threads::IsUnderValgrind() ) )
 	{
-		FilterCreationMeasureStack_c tCreateMeter;
-		auto iNewDelta = tCreateMeter.MockMeasureStack ( 100 );
+		StringBuilder_c sName;
+		sName << "MANTICORE_" << szEnv;
+		iNewSize = val_from_env ( sName.cstr(), 0 );
+
+		if ( !iNewSize )
+		{
+			iNewSize = MOCK::MockMeasure();
+			bMocked = true;
+
 #ifdef NDEBUG
-		if ( iDelta && iDelta<iNewDelta )
-			sphWarning ( "Compiled-in value KNOWN_FILTER_SIZE (%d) is less then measured (%d). Consider to fix the value!", iDelta, iNewDelta );
+			if ( COMPILEDVAL && COMPILEDVAL < iNewSize )
+				sphWarning ( "Compiled-in value %s (%d) is less than measured (%d). Consider to fix the value!", szEnv, COMPILEDVAL, iNewSize );
 #endif
-		iDelta = iNewDelta;
+		}
+		iSize = iNewSize;
+		if ( bMocked )
+			sphLogDebug ( "%s is %d. Consider to add env MANTICORE_%s=%d to store this value persistent for this binary", szReport, iSize, szEnv, iNewSize );
+		else
+			sphLogDebug ( "%s %d (from env MANTICORE_%s)", szReport, iSize, szEnv );
+	} else
+	{
+		sphLogDebug ( "%s is %d (compiled-in)", szReport, iSize );
 	}
 
-	sphLogDebug ( "filter stack delta %d", iDelta );
-	SetFilterStackItemSize ( iDelta );
+	MOCK::PublishValue ( iSize );
+}
+
+
+void DetermineNodeItemStackSize()
+{
+	// some values for x86_64: clang 12.0.1 relwithdebinfo = 768, debug = 4208. gcc 9.3 relwithdebinfo = 16, debug = 256
+#ifdef KNOWN_CREATE_SIZE
+	DetermineStackSize<CreateExprStackSize_c, KNOWN_CREATE_SIZE>
+#else
+	DetermineStackSize<CreateExprStackSize_c, 0>
+#endif
+			( "expression stack for creation", "KNOWN_CREATE_SIZE" );
+
+	// some values for x86_64: clang 12.0.1 relwithdebinfo = 32, debug = 48. gcc 9.3 relwithdebinfo = 48, debug = 48
+#ifdef KNOWN_EXPR_SIZE
+	DetermineStackSize<EvalExprStackSize_c, KNOWN_EXPR_SIZE>
+#else
+	DetermineStackSize<EvalExprStackSize_c, 0>
+#endif
+			( "expression stack for eval/deletion", "KNOWN_EXPR_SIZE" );
+}
+
+void DetermineFilterItemStackSize ()
+{
+	// some values for x86_64: clang 12.0.1 relwithdebinfo = 208, debug = 400. gcc 9.3 relwithdebinfo = 240, debug = 272
+#ifdef KNOWN_FILTER_SIZE
+	DetermineStackSize<FilterCreationMeasureStack_c, KNOWN_FILTER_SIZE>
+#else
+	DetermineStackSize<FilterCreationMeasureStack_c, 0>
+#endif
+			( "filter stack delta", "KNOWN_FILTER_SIZE" );
 }