Skip to content

Commit 66a2089

Browse files
committed
Add test file
1 parent 046590f commit 66a2089

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include "precompiled.hpp"
25+
26+
#ifndef PRODUCT
27+
#ifndef ZERO
28+
29+
#include "asm/macroAssembler.hpp"
30+
#include "compiler/disassembler.hpp"
31+
#include "memory/resourceArea.hpp"
32+
#include "unittest.hpp"
33+
34+
#include <regex>
35+
36+
static const char* replace_addr_expr(const char* str)
37+
{
38+
// Remove any address expression "0x0123456789abcdef" found in order to
39+
// aid string comparison. Also remove any trailing printout from a padded
40+
// buffer.
41+
42+
std::basic_string<char> tmp = std::regex_replace(str, std::regex("0x[0-9a-fA-F]+"), "<addr>");
43+
std::basic_string<char> red = std::regex_replace(tmp, std::regex("\\s+<addr>:\\s+\\.inst\\t<addr> ; undefined"), "");
44+
45+
return os::strdup(red.c_str());
46+
}
47+
48+
static const char* delete_header_line(const char* str)
49+
{
50+
// Remove (second) header line in output, e.g.:
51+
// Decoding CodeBlob, name: CodeStringTest, at [<addr>, <addr>] 8 bytes\n
52+
53+
std::basic_string<char> red = std::regex_replace(str, std::regex("Decoding.+bytes\\n"), "");
54+
55+
return os::strdup(red.c_str());
56+
}
57+
58+
static void asm_remarks_check(const AsmRemarks &rem1,
59+
const AsmRemarks &rem2)
60+
{
61+
ASSERT_EQ(rem1.ref(), rem2.ref()) << "Should share the same collection.";
62+
}
63+
64+
static void dbg_strings_check(const DbgStrings &dbg1,
65+
const DbgStrings &dbg2)
66+
{
67+
ASSERT_EQ(dbg1.ref(), dbg2.ref()) << "Should share the same collection.";
68+
}
69+
70+
static void disasm_string_check(CodeBuffer* cbuf, CodeBlob* blob)
71+
{
72+
if (Disassembler::is_abstract())
73+
{
74+
return; // No disassembler available (no comments will be used).
75+
}
76+
stringStream out1, out2;
77+
78+
Disassembler::decode(cbuf->insts_begin(), cbuf->insts_end(), &out1, &cbuf->asm_remarks());
79+
Disassembler::decode(blob->code_begin(), blob->code_end(), &out2, &blob->asm_remarks());
80+
81+
EXPECT_STREQ(replace_addr_expr(out1.as_string()),
82+
replace_addr_expr(out2.as_string()))
83+
<< "1. Output should be identical.";
84+
85+
stringStream out3;
86+
87+
Disassembler::decode(blob, &out3);
88+
89+
EXPECT_STREQ(replace_addr_expr(out2.as_string()),
90+
replace_addr_expr(delete_header_line(out3.as_string())))
91+
<< "2. Output should be identical.";
92+
}
93+
94+
static void copy_and_compare(CodeBuffer* cbuf)
95+
{
96+
bool remarks_empty = cbuf->asm_remarks().is_empty();
97+
bool strings_empty = cbuf->dbg_strings().is_empty();
98+
99+
BufferBlob* blob = BufferBlob::create("CodeBuffer Copy&Compare", cbuf);
100+
101+
// 1. Check Assembly Remarks are shared by buffer and blob.
102+
asm_remarks_check(cbuf->asm_remarks(), blob->asm_remarks());
103+
104+
// 2. Check Debug Strings are shared by buffer and blob.
105+
dbg_strings_check(cbuf->dbg_strings(), blob->dbg_strings());
106+
107+
// 3. Check that the disassembly output matches.
108+
disasm_string_check(cbuf, blob);
109+
110+
BufferBlob::free(blob);
111+
112+
ASSERT_EQ(remarks_empty, cbuf->asm_remarks().is_empty())
113+
<< "Expecting property to be unchanged.";
114+
ASSERT_EQ(strings_empty, cbuf->dbg_strings().is_empty())
115+
<< "Expecting property to be unchanged.";
116+
}
117+
118+
static void code_buffer_test()
119+
{
120+
constexpr int BUF_SZ = 256;
121+
122+
ResourceMark rm;
123+
CodeBuffer cbuf("CodeStringTest", BUF_SZ, BUF_SZ);
124+
MacroAssembler as(&cbuf);
125+
126+
ASSERT_TRUE(cbuf.asm_remarks().is_empty());
127+
ASSERT_TRUE(cbuf.dbg_strings().is_empty());
128+
129+
ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty());
130+
ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty());
131+
132+
int re, sz, n;
133+
134+
re = cbuf.insts_remaining();
135+
136+
// 1. Generate a first entry.
137+
as.block_comment("First block comment.");
138+
as.nop();
139+
140+
sz = re - cbuf.insts_remaining();
141+
142+
ASSERT_TRUE(sz > 0);
143+
144+
ASSERT_FALSE(cbuf.asm_remarks().is_empty());
145+
ASSERT_TRUE(cbuf.dbg_strings().is_empty());
146+
147+
ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty());
148+
ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty());
149+
150+
copy_and_compare(&cbuf);
151+
152+
n = re/sz;
153+
ASSERT_TRUE(n > 0);
154+
155+
// 2. Generate additional entries without causing the buffer to expand.
156+
for (unsigned i = 0; i < unsigned(n)/2; i++)
157+
{
158+
ASSERT_FALSE(cbuf.insts()->maybe_expand_to_ensure_remaining(sz));
159+
ASSERT_TRUE(cbuf.insts_remaining()/sz >= n/2);
160+
161+
stringStream strm;
162+
strm.print("Comment No. %d", i);
163+
as.block_comment(strm.as_string());
164+
as.nop();
165+
}
166+
ASSERT_FALSE(cbuf.asm_remarks().is_empty());
167+
168+
copy_and_compare(&cbuf);
169+
170+
re = cbuf.insts_remaining();
171+
172+
// 3. Generate a single code with a debug string.
173+
as.unimplemented("First debug string.");
174+
175+
ASSERT_FALSE(cbuf.asm_remarks().is_empty());
176+
ASSERT_FALSE(cbuf.dbg_strings().is_empty());
177+
178+
sz = re - cbuf.insts_remaining();
179+
n = (re - sz)/sz;
180+
ASSERT_TRUE(n > 0);
181+
182+
// 4. Generate additional code with debug strings.
183+
for (unsigned i = 0; i < unsigned(n); i++)
184+
{
185+
ASSERT_TRUE(cbuf.insts_remaining() >= sz);
186+
187+
stringStream strm;
188+
strm.print("Fixed address string No. %d", i);
189+
as.unimplemented(strm.as_string());
190+
}
191+
ASSERT_TRUE(cbuf.insts_remaining() >= 0);
192+
193+
ASSERT_FALSE(cbuf.asm_remarks().is_empty());
194+
ASSERT_FALSE(cbuf.dbg_strings().is_empty());
195+
196+
ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty());
197+
ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty());
198+
199+
copy_and_compare(&cbuf);
200+
}
201+
202+
static void buffer_blob_test()
203+
{
204+
constexpr int BUF_SZ = 256;
205+
206+
ResourceMark rm;
207+
BufferBlob* blob = BufferBlob::create("BufferBlob Test", BUF_SZ);
208+
CodeBuffer cbuf(blob);
209+
MacroAssembler as(&cbuf);
210+
211+
ASSERT_FALSE(cbuf.insts()->has_locs());
212+
213+
// The x86-64 version of 'stop' will use relocation info. that will result
214+
// in tainting the location start and limit if no location info. buffer is
215+
// present.
216+
static uint8_t s_loc_buf[BUF_SZ]; // Raw memory buffer used for relocInfo.
217+
cbuf.insts()->initialize_shared_locs((relocInfo*)&s_loc_buf[0], BUF_SZ);
218+
219+
int re = cbuf.insts_remaining();
220+
221+
as.block_comment("First block comment.");
222+
as.nop();
223+
as.unimplemented("First debug string.");
224+
225+
int sz = re - cbuf.insts_remaining();
226+
227+
ASSERT_TRUE(sz > 0);
228+
constexpr int LIM_GEN = 51; // Limit number of entries generated.
229+
230+
for (unsigned i = 0; i < LIM_GEN; i++)
231+
{
232+
if (cbuf.insts_remaining() < sz) break;
233+
234+
stringStream strm1;
235+
strm1.print("Comment No. %d", i);
236+
as.block_comment(strm1.as_string());
237+
as.nop();
238+
239+
stringStream strm2;
240+
strm2.print("Fixed address string No. %d", i);
241+
as.unimplemented(strm2.as_string());
242+
}
243+
ASSERT_TRUE(cbuf.insts_remaining() >= 0);
244+
245+
ASSERT_FALSE(cbuf.asm_remarks().is_empty());
246+
ASSERT_FALSE(cbuf.dbg_strings().is_empty());
247+
248+
copy_and_compare(&cbuf);
249+
250+
ASSERT_TRUE(blob->asm_remarks().is_empty());
251+
ASSERT_TRUE(blob->dbg_strings().is_empty());
252+
253+
BufferBlob::free(blob);
254+
}
255+
256+
TEST_VM(codestrings, validate)
257+
{
258+
code_buffer_test();
259+
buffer_blob_test();
260+
}
261+
262+
#endif // not ZERO
263+
#endif // not PRODUCT

0 commit comments

Comments
 (0)