4949 * @run driver TestTransparentHugePagesHeap Serial
5050*/
5151
52+ import java .math .BigInteger ;
5253import java .nio .file .Files ;
5354import java .nio .file .Path ;
5455import java .nio .file .Paths ;
@@ -98,47 +99,76 @@ public static void main(String args[]) throws Exception {
9899 class VerifyTHPEnabledForHeap {
99100
100101 public static void main (String args []) throws Exception {
101- String heapAddress = readHeapAddressInLog ();
102+ // Extract the heap start from pagesize logging
103+ BigInteger heapStart = extractHeapStartFromLog ();
104+
102105 Path smaps = makeSmapsCopy ();
103106
104- final Pattern heapSection = Pattern .compile ("^" + heapAddress + " .*" );
105- final Pattern thpEligible = Pattern .compile ("THPeligible:\\ s+(\\ d)\\ s*" );
107+ final Pattern addressRangePattern = Pattern .compile ("([0-9a-f]*?)-([0-9a-f]*?) .*" );
108+ final Pattern thpEligiblePattern = Pattern .compile ("THPeligible:\\ s+(\\ d)\\ s*" );
106109
107110 Scanner smapsFile = new Scanner (smaps );
108111 while (smapsFile .hasNextLine ()) {
109- Matcher heapMatcher = heapSection .matcher (smapsFile .nextLine ());
110-
111- if (heapMatcher .matches ()) {
112- // Found the first heap section, verify that it is THP eligible
113- while (smapsFile .hasNextLine ()) {
114- Matcher m = thpEligible .matcher (smapsFile .nextLine ());
115- if (m .matches ()) {
116- if (Integer .parseInt (m .group (1 )) == 1 ) {
117- // THPeligible is 1, heap can be backed by huge pages
118- return ;
119- }
120-
121- throw new RuntimeException ("First heap section at 0x" + heapAddress + " is not THPeligible" );
122- }
112+ Matcher addressRangeMatcher = addressRangePattern .matcher (smapsFile .nextLine ());
113+ if (!addressRangeMatcher .matches ()) {
114+ continue ;
115+ }
116+
117+ // Found an address range line in the smaps file
118+
119+ BigInteger addressStart = new BigInteger (addressRangeMatcher .group (1 ), 16 );
120+ BigInteger addressEnd = new BigInteger (addressRangeMatcher .group (2 ), 16 );
121+
122+ // Linux sometimes merges adjacent VMAs so we can't search for a range that
123+ // exactly matches the heap range. Instead we look for the first range that
124+ // contains the start of the heap and verify that that range is THP eligible.
125+
126+ if (addressStart .compareTo (heapStart ) > 0 || heapStart .compareTo (addressEnd ) >= 0 ) {
127+ continue ;
128+ }
129+
130+ // Found a range that contains the start of the heap, verify that it is THP eligible.
131+
132+ while (smapsFile .hasNextLine ()) {
133+ Matcher m = thpEligiblePattern .matcher (smapsFile .nextLine ());
134+ if (!m .matches ()) {
135+ continue ;
123136 }
137+
138+ // Found the THPeligible line
139+
140+ if (m .group (1 ).equals ("1" )) {
141+ // Success - THPeligible is 1, heap can be backed by huge pages
142+ return ;
143+ }
144+
145+ throw new RuntimeException ("The address range 0x" + addressStart .toString (16 )
146+ + "-0x" + addressEnd .toString (16 )
147+ + " that contains the heap start" + heapStart
148+ + " is not THPeligible" );
124149 }
150+
151+ throw new RuntimeException ("Couldn't find THPeligible in the smaps file" );
125152 }
126153
127- // Failed to verify THP for heap
128- throw new RuntimeException ("Could not find heap section in smaps file" );
154+ throw new RuntimeException ("Could not find an address range containing the heap start " + heapStart + " in the smaps file" );
129155 }
130156
131- private static String readHeapAddressInLog () throws Exception {
132- final Pattern heapAddress = Pattern .compile (".* Heap: .*base=(0x[0-9A-Fa-f]*).*" );
157+ private static BigInteger extractHeapStartFromLog () throws Exception {
158+ // [0.041s][info][pagesize] Heap: min=128M max=128M base=0x0000ffff5c600000 size=128M page_size=2M
159+ final Pattern heapAddress = Pattern .compile (".* Heap: .*base=0x([0-9A-Fa-f]*).*" );
133160
134161 Scanner logFile = new Scanner (Paths .get ("thp-" + ProcessHandle .current ().pid () + ".log" ));
135162 while (logFile .hasNextLine ()) {
136- Matcher m = heapAddress .matcher (logFile .nextLine ());
163+ String line = logFile .nextLine ();
164+
165+ Matcher m = heapAddress .matcher (line );
137166 if (m .matches ()) {
138- return Long . toHexString ( Long . decode ( m .group (1 )) );
167+ return new BigInteger ( m .group (1 ), 16 );
139168 }
140169 }
141- throw new RuntimeException ("Failed to parse heap address, failing test" );
170+
171+ throw new RuntimeException ("Failed to find heap start" );
142172 }
143173
144174 private static Path makeSmapsCopy () throws Exception {
@@ -149,4 +179,3 @@ private static Path makeSmapsCopy() throws Exception {
149179 }
150180 }
151181}
152-
0 commit comments