Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Unified Diff: test/cctest/test-api.cc

Side-by-side diff isn't available for this file because of its large size.
Issue 2482913002: [ic] Resurrect access checks for primitive and global proxy receivers. (Closed)
Patch Set: Addressing comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
Download patch
« no previous file with comments | « src/objects-printer.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 38a9f45e2ff85a6d9b77210102b28a224732f755..6c0655a8f49eff801e5ba69e6e7a60205436d8ce 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -21736,10 +21736,6 @@ TEST(ScopedMicrotasks) {
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
}
-#ifdef ENABLE_DISASSEMBLER
-// FLAG_test_primary_stub_cache and FLAG_test_secondary_stub_cache are read
-// only when ENABLE_DISASSEMBLER is not defined.
-
namespace {
int probes_counter = 0;
@@ -21757,6 +21753,14 @@ int* LookupCounter(const char* name) {
return NULL;
}
+} // namespace
+
+#ifdef ENABLE_DISASSEMBLER
+// FLAG_test_primary_stub_cache and FLAG_test_secondary_stub_cache are read
+// only when ENABLE_DISASSEMBLER is not defined.
+
+namespace {
+
const char* kMegamorphicTestProgram =
"function CreateClass(name) {\n"
" var src = \n"
@@ -22658,6 +22662,7 @@ TEST(AccessCheckThrows) {
// Create a context and set an x property on it's global object.
LocalContext context0(NULL, global_template);
v8::Local<v8::Object> global0 = context0->Global();
+ CHECK(global0->Set(context0.local(), v8_str("x"), global0).FromJust());
// Create a context with a different security token so that the
// failed access check callback will be called on each access.
@@ -22712,6 +22717,128 @@ TEST(AccessCheckThrows) {
isolate->SetFailedAccessCheckCallbackFunction(NULL);
}
+TEST(AccessCheckInIC) {
+ // The test does not work with interpreter because bytecode handlers taken
+ // from the snapshot already refer to ICs with disabled counters and there
+ // is no way to trigger bytecode handlers recompilation.
+ if (i::FLAG_ignition || i::FLAG_turbo) return;
+
+ i::FLAG_native_code_counters = true;
+ i::FLAG_crankshaft = false;
+ i::FLAG_turbo = false;
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ create_params.counter_lookup_callback = LookupCounter;
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ LocalContext env(isolate);
+ v8::HandleScope scope(isolate);
+
+ {
+ // Enforce recompilation of IC stubs that access megamorphic stub cache
+ // to respect enabled native code counters and stub cache test flags.
+ i::CodeStub::Major code_stub_keys[] = {
+ i::CodeStub::LoadIC, i::CodeStub::LoadICTrampoline,
+ i::CodeStub::KeyedLoadICTF, i::CodeStub::KeyedLoadICTrampolineTF,
+ i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline,
+ i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline,
+ };
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::Heap* heap = i_isolate->heap();
+ i::Handle<i::UnseededNumberDictionary> dict(heap->code_stubs());
+ for (size_t i = 0; i < arraysize(code_stub_keys); i++) {
+ dict = i::UnseededNumberDictionary::DeleteKey(dict, code_stub_keys[i]);
+ }
+ heap->SetRootCodeStubs(*dict);
+ }
+
+ // Create an ObjectTemplate for global objects and install access
+ // check callbacks that will block access.
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ global_template->SetAccessCheckCallback(AccessCounter);
+
+ // Create a context and set an x property on its global object.
+ LocalContext context0(isolate, NULL, global_template);
+ v8::Local<v8::Object> global0 = context0->Global();
+ CHECK(global0->Set(context0.local(), v8_str("x"), global0).FromJust());
+
+ // Create a context with a different security token so that the
+ // failed access check callback will be called on each access.
+ LocalContext context1(isolate, NULL, global_template);
+ CHECK(context1->Global()
+ ->Set(context1.local(), v8_str("other"), global0)
+ .FromJust());
+
+ // Set different security tokens.
+ Local<Value> token0 = v8_str("token0");
+ context0.local()->SetSecurityToken(token0);
+ context1.local()->SetSecurityToken(v8_str("token1"));
+
+ int initial_probes = probes_counter;
+ int initial_misses = misses_counter;
+ int initial_updates = updates_counter;
+ access_count = 0;
+
+ // Create megamorphic load ic with a handler for "global0.x" compiled for
+ // context0.
+ CompileRun(context0.local(),
+ "Number(1).__proto__.x = null;\n"
+ "String(1).__proto__.x = null;\n"
+ "function get0(o) { return o.x; };\n"
+ "get0({x:1});\n" // premonomorphic
+ "get0({x:1,a:0});\n" // monomorphic
+ "get0({x:1,b:0});\n" // polymorphic
+ "get0('str');\n"
+ "get0(1.1);\n"
+ "get0(this);\n" // megamorphic
+ "");
+ CHECK_EQ(0, probes_counter - initial_probes);
+ CHECK_EQ(0, misses_counter - initial_misses);
+ CHECK_EQ(5, updates_counter - initial_updates);
+
+ // Create megamorphic load ic in context1.
+ CompileRun(context1.local(),
+ "function get1(o) { return o.x; };\n"
+ "get1({x:1});\n" // premonomorphic
+ "get1({x:1,a:0});\n" // monomorphic
+ "get1({x:1,b:0});\n" // polymorphic
+ "get1({x:1,c:0});\n"
+ "get1({x:1,d:0});\n"
+ "get1({x:1,e:0});\n" // megamorphic
+ "");
+ CHECK_EQ(0, access_count);
+ CHECK_EQ(0, probes_counter - initial_probes);
+ CHECK_EQ(0, misses_counter - initial_misses);
+ CHECK_EQ(10, updates_counter - initial_updates);
+
+ // Feed the |other| to the load ic and ensure that it doesn't pick the
+ // handler for "global0.x" compiled for context0 from the megamorphic
+ // cache but create another handler for "global0.x" compiled for context1
+ // and ensure the access check callback is triggered.
+ CompileRun(context1.local(), "get1(other)");
+ CHECK_EQ(1, access_count); // Access check callback must be triggered.
+
+ // Feed the primitive objects to the load ic and ensure that it doesn't
+ // pick handlers for primitive maps from the megamorphic stub cache even
+ // if the security token matches.
+ context1.local()->SetSecurityToken(token0);
+ CHECK(CompileRun(context1.local(), "get1(1.1)")
+ .ToLocalChecked()
+ ->IsUndefined());
+ CHECK(CompileRun(context1.local(), "get1('str')")
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ CHECK_EQ(1, access_count); // Access check callback must be triggered.
+ CHECK_EQ(3, probes_counter - initial_probes);
+ CHECK_EQ(0, misses_counter - initial_misses);
+ CHECK_EQ(13, updates_counter - initial_updates);
+ }
+ isolate->Dispose();
+}
class RequestInterruptTestBase {
public:
« no previous file with comments | « src/objects-printer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698