Commit 8c04c33f authored by vogelheim's avatar vogelheim Committed by Commit bot

Generalize 'fast accessor' tests to work with --always-opt.

BUG=508898
LOG=N

Review URL: https://codereview.chromium.org/1588053002

Cr-Commit-Position: refs/heads/master@{#33297}
parent ef21fb2d
...@@ -28,8 +28,6 @@ v8::experimental::FastAccessorBuilder* FastAccessor(v8::Isolate* isolate) { ...@@ -28,8 +28,6 @@ v8::experimental::FastAccessorBuilder* FastAccessor(v8::Isolate* isolate) {
TEST(FastAccessors) { TEST(FastAccessors) {
if (i::FLAG_always_opt) return;
v8::Isolate* isolate = CcTest::isolate(); v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
LocalContext env; LocalContext env;
......
...@@ -13,20 +13,47 @@ ...@@ -13,20 +13,47 @@
namespace { namespace {
// These tests mean to exercise v8::FastAccessorBuilder. Since initially the // These tests mean to exercise v8::FastAccessorBuilder. Since initially the
// "native" accessor will get called, we need to 'warmup' any accessor first, // "native" accessor will get called, we need to "warmup" any accessor first,
// to make sure we're actually testing the v8::FastAccessorBuilder result. // to make sure we're actually testing the v8::FastAccessorBuilder result.
// To accomplish this, we will // To accomplish this, we will
// - call each accesssor N times before the actual test. // - call each accesssor N times before the actual test.
// - wrap that call in a function, so that all such calls will go // - wrap that call in a function, so that all such calls will go
// through a single call site. // through a single call site.
// - bloat that function with a very long comment to prevent its inlining.
// - register a native accessor which is different from the build one // - register a native accessor which is different from the build one
// (so that our tests will always fail if we don't end up in the 'fast' // (so that our tests will always fail if we don't end up in the 'fast'
// accessor) // accessor).
// //
// This doesn't work if the src function is inlined - as it is when // FN_WARMUP(name, src) define a JS function "name" with body "src".
// --always-opt is enabled - since then every inlined functino is its own // It adds the INLINE_SPOILER to prevent inlining and will call name()
// callsite. Hence most test will check for i::FLAG_always_opt. // repeatedly to guarantee it's "warm".
#define WARMUP(src) "for(i = 0; i < 2; i++) { " src " } " //
// Use:
// CompileRun(FN_WARMUP("fn", "return something();"));
// ExpectXXX("fn(1234)", 5678);
#define INLINE_SPOILER \
" /* " \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"*/ " // 16 lines * 64 'X' =~ 1024 character comment.
#define FN_WARMUP(name, src) \
"function " name "() { " src INLINE_SPOILER \
" }; for(i = 0; i < 2; i++) { " name "() } "
static void NativePropertyAccessor( static void NativePropertyAccessor(
const v8::FunctionCallbackInfo<v8::Value>& info) { const v8::FunctionCallbackInfo<v8::Value>& info) {
...@@ -38,8 +65,6 @@ static void NativePropertyAccessor( ...@@ -38,8 +65,6 @@ static void NativePropertyAccessor(
// Build a simple "fast accessor" and verify that it is being called. // Build a simple "fast accessor" and verify that it is being called.
TEST(FastAccessor) { TEST(FastAccessor) {
if (i::FLAG_always_opt) return;
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
...@@ -65,8 +90,7 @@ TEST(FastAccessor) { ...@@ -65,8 +90,7 @@ TEST(FastAccessor) {
.FromJust()); .FromJust());
// Wrap f.barf + IC warmup. // Wrap f.barf + IC warmup.
CompileRun( CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf"));
"function barf() { f = new foo(); return f.barf }; " WARMUP("barf()"));
ExpectInt32("f = new foo(); f.bar", 123); ExpectInt32("f = new foo(); f.bar", 123);
ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site.
...@@ -88,8 +112,6 @@ void AddInternalFieldAccessor(v8::Isolate* isolate, ...@@ -88,8 +112,6 @@ void AddInternalFieldAccessor(v8::Isolate* isolate,
// "Fast" accessor that accesses an internal field. // "Fast" accessor that accesses an internal field.
TEST(FastAccessorWithInternalField) { TEST(FastAccessorWithInternalField) {
if (i::FLAG_always_opt) return;
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
...@@ -107,9 +129,9 @@ TEST(FastAccessorWithInternalField) { ...@@ -107,9 +129,9 @@ TEST(FastAccessorWithInternalField) {
CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
// Warmup. // Warmup.
CompileRun("function field0() { return obj.field0 }; " WARMUP("field0()")); CompileRun(FN_WARMUP("field0", "return obj.field0"));
CompileRun("function field1() { return obj.field1 }; " WARMUP("field1()")); CompileRun(FN_WARMUP("field1", "return obj.field1"));
CompileRun("function field2() { return obj.field2 }; " WARMUP("field2()")); CompileRun(FN_WARMUP("field2", "return obj.field2"));
// Access fields. // Access fields.
ExpectString("field0()", "Hi there!"); ExpectString("field0()", "Hi there!");
...@@ -120,8 +142,6 @@ TEST(FastAccessorWithInternalField) { ...@@ -120,8 +142,6 @@ TEST(FastAccessorWithInternalField) {
// "Fast" accessor with control flow via ...OrReturnNull methods. // "Fast" accessor with control flow via ...OrReturnNull methods.
TEST(FastAccessorOrReturnNull) { TEST(FastAccessorOrReturnNull) {
if (i::FLAG_always_opt) return;
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
...@@ -154,16 +174,14 @@ TEST(FastAccessorOrReturnNull) { ...@@ -154,16 +174,14 @@ TEST(FastAccessorOrReturnNull) {
CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
// CheckNotZeroOrReturnNull: // CheckNotZeroOrReturnNull:
CompileRun( CompileRun(FN_WARMUP("nullcheck", "return obj.nullcheck"));
"function nullcheck() { return obj.nullcheck }; " WARMUP("nullcheck()"));
obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate); obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate);
ExpectInt32("nullcheck()", 5); ExpectInt32("nullcheck()", 5);
obj->SetAlignedPointerInInternalField(0, nullptr); obj->SetAlignedPointerInInternalField(0, nullptr);
ExpectNull("nullcheck()"); ExpectNull("nullcheck()");
// CheckFlagSetOrReturnNull: // CheckFlagSetOrReturnNull:
CompileRun( CompileRun(FN_WARMUP("maskcheck", "return obj.maskcheck"));
"function maskcheck() { return obj.maskcheck }; " WARMUP("maskcheck()"));
obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xf0)); obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xf0));
ExpectInt32("maskcheck()", 42); ExpectInt32("maskcheck()", 42);
obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xfe)); obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xfe));
...@@ -173,8 +191,6 @@ TEST(FastAccessorOrReturnNull) { ...@@ -173,8 +191,6 @@ TEST(FastAccessorOrReturnNull) {
// "Fast" accessor with simple control flow via explicit labels. // "Fast" accessor with simple control flow via explicit labels.
TEST(FastAccessorControlFlowWithLabels) { TEST(FastAccessorControlFlowWithLabels) {
if (i::FLAG_always_opt) return;
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
...@@ -200,7 +216,7 @@ TEST(FastAccessorControlFlowWithLabels) { ...@@ -200,7 +216,7 @@ TEST(FastAccessorControlFlowWithLabels) {
CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
// CheckNotZeroOrReturnNull: // CheckNotZeroOrReturnNull:
CompileRun("function isnull() { return obj.isnull }; " WARMUP("isnull()")); CompileRun(FN_WARMUP("isnull", "return obj.isnull"));
obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate); obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate);
ExpectInt32("isnull()", 1); ExpectInt32("isnull()", 1);
obj->SetAlignedPointerInInternalField(0, nullptr); obj->SetAlignedPointerInInternalField(0, nullptr);
...@@ -210,8 +226,6 @@ TEST(FastAccessorControlFlowWithLabels) { ...@@ -210,8 +226,6 @@ TEST(FastAccessorControlFlowWithLabels) {
// "Fast" accessor, loading things. // "Fast" accessor, loading things.
TEST(FastAccessorLoad) { TEST(FastAccessorLoad) {
if (i::FLAG_always_opt) return;
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
...@@ -261,7 +275,7 @@ TEST(FastAccessorLoad) { ...@@ -261,7 +275,7 @@ TEST(FastAccessorLoad) {
CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
// Access val.intval: // Access val.intval:
CompileRun("function nonzero() { return obj.nonzero }; " WARMUP("nonzero()")); CompileRun(FN_WARMUP("nonzero", "return obj.nonzero"));
ExpectInt32("nonzero()", 1); ExpectInt32("nonzero()", 1);
val.intval = 0; val.intval = 0;
ExpectInt32("nonzero()", 0); ExpectInt32("nonzero()", 0);
...@@ -269,6 +283,6 @@ TEST(FastAccessorLoad) { ...@@ -269,6 +283,6 @@ TEST(FastAccessorLoad) {
ExpectInt32("nonzero()", 1); ExpectInt32("nonzero()", 1);
// Access val.v8val: // Access val.v8val:
CompileRun("function loadval() { return obj.loadval }; " WARMUP("loadval()")); CompileRun(FN_WARMUP("loadval", "return obj.loadval"));
ExpectString("loadval()", "Hello"); ExpectString("loadval()", "Hello");
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment