Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 | 6 |
| 7 #include "include/v8.h" | 7 #include "include/v8.h" |
| 8 #include "include/v8-experimental.h" | 8 #include "include/v8-experimental.h" |
| 9 | 9 |
| 10 #include "src/api.h" | 10 #include "src/api.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 .FromJust()); | 106 .FromJust()); |
| 107 | 107 |
| 108 // Wrap f.barf + IC warmup. | 108 // Wrap f.barf + IC warmup. |
| 109 CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf")); | 109 CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf")); |
| 110 | 110 |
| 111 ExpectInt32("f = new foo(); f.bar", 123); | 111 ExpectInt32("f = new foo(); f.bar", 123); |
| 112 ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. | 112 ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. |
| 113 ExpectInt32("barf()", 124); // Call via warmed-up callsite. | 113 ExpectInt32("barf()", 124); // Call via warmed-up callsite. |
| 114 } | 114 } |
| 115 | 115 |
| 116 | |
| 117 void AddInternalFieldAccessor(v8::Isolate* isolate, | 116 void AddInternalFieldAccessor(v8::Isolate* isolate, |
| 118 v8::Local<v8::Template> templ, const char* name, | 117 v8::Local<v8::Template> templ, const char* name, |
| 119 int field_no) { | 118 int field_no, bool useUnsafeLoader) { |
| 120 auto builder = v8::experimental::FastAccessorBuilder::New(isolate); | 119 auto builder = v8::experimental::FastAccessorBuilder::New(isolate); |
| 121 builder->ReturnValue( | 120 |
| 122 builder->LoadInternalField(builder->GetReceiver(), field_no)); | 121 if (useUnsafeLoader) { |
| 122 builder->ReturnValue( | |
| 123 builder->LoadInternalFieldUnsafe(builder->GetReceiver(), field_no)); | |
| 124 } else { | |
| 125 builder->ReturnValue( | |
| 126 builder->LoadInternalField(builder->GetReceiver(), field_no)); | |
| 127 } | |
| 128 | |
| 123 templ->SetAccessorProperty(v8_str(name), | 129 templ->SetAccessorProperty(v8_str(name), |
| 124 v8::FunctionTemplate::NewWithFastHandler( | 130 v8::FunctionTemplate::NewWithFastHandler( |
| 125 isolate, NativePropertyAccessor, builder)); | 131 isolate, NativePropertyAccessor, builder)); |
| 126 } | 132 } |
| 127 | 133 |
| 128 | 134 |
| 129 // "Fast" accessor that accesses an internal field. | 135 // "Fast" accessor that accesses an internal field. |
| 130 TEST(FastAccessorWithInternalField) { | 136 TEST(FastAccessorWithInternalField) { |
| 131 // Crankshaft support for fast accessors is not implemented; crankshafted | 137 // Crankshaft support for fast accessors is not implemented; crankshafted |
| 132 // code uses the slow accessor which breaks this test's expectations. | 138 // code uses the slow accessor which breaks this test's expectations. |
| 133 v8::internal::FLAG_always_opt = false; | 139 v8::internal::FLAG_always_opt = false; |
| 134 LocalContext env; | 140 LocalContext env; |
| 135 v8::Isolate* isolate = env->GetIsolate(); | 141 v8::Isolate* isolate = env->GetIsolate(); |
| 136 v8::HandleScope scope(isolate); | 142 v8::HandleScope scope(isolate); |
| 137 | 143 |
| 138 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); | 144 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); |
| 139 foo->SetInternalFieldCount(3); | 145 foo->SetInternalFieldCount(3); |
| 140 AddInternalFieldAccessor(isolate, foo, "field0", 0); | 146 AddInternalFieldAccessor(isolate, foo, "field0", 0, false); |
| 141 AddInternalFieldAccessor(isolate, foo, "field1", 1); | 147 AddInternalFieldAccessor(isolate, foo, "field1", 1, false); |
| 142 AddInternalFieldAccessor(isolate, foo, "field2", 2); | 148 AddInternalFieldAccessor(isolate, foo, "field2", 2, false); |
| 143 | 149 |
| 144 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. | 150 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. |
| 145 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); | 151 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); |
| 152 obj->SetInternalField(0, v8_str("Hi there!")); | |
| 153 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); | |
| 154 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); | |
| 155 | |
| 156 // Warmup. | |
| 157 CompileRun(FN_WARMUP("field0", "return obj.field0")); | |
| 158 CompileRun(FN_WARMUP("field1", "return obj.field1")); | |
| 159 CompileRun(FN_WARMUP("field2", "return obj.field2")); | |
| 160 | |
| 161 // Access fields. | |
| 162 ExpectString("field0()", "Hi there!"); | |
| 163 ExpectInt32("field1()", 4321); | |
| 164 ExpectUndefined("field2()"); | |
| 165 } | |
| 166 | |
| 167 // "Fast" accessor that accesses an internal field using the fast(er) but unsafe | |
| 168 // implementation of LoadInternalField. | |
| 169 TEST(FastAccessorLoadInternalFieldUnsafe) { | |
|
vogelheim
2016/07/27 09:50:56
nitpick: If we add the Unsafe-with-crash-when-FLAG
Alfonso
2016/07/28 14:39:13
Refactoring away the common part for the 3 tests.
| |
| 170 // Crankshaft support for fast accessors is not implemented; crankshafted | |
| 171 // code uses the slow accessor which breaks this test's expectations. | |
| 172 v8::internal::FLAG_always_opt = false; | |
| 173 LocalContext env; | |
| 174 v8::Isolate* isolate = env->GetIsolate(); | |
| 175 v8::HandleScope scope(isolate); | |
| 176 | |
| 177 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); | |
| 178 foo->SetInternalFieldCount(3); | |
| 179 AddInternalFieldAccessor(isolate, foo, "field0", 0, true); | |
| 180 AddInternalFieldAccessor(isolate, foo, "field1", 1, true); | |
| 181 AddInternalFieldAccessor(isolate, foo, "field2", 2, true); | |
| 182 | |
| 183 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. | |
| 184 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); | |
| 146 obj->SetInternalField(0, v8_str("Hi there!")); | 185 obj->SetInternalField(0, v8_str("Hi there!")); |
| 147 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); | 186 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); |
| 148 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); | 187 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); |
| 149 | 188 |
| 150 // Warmup. | 189 // Warmup. |
| 151 CompileRun(FN_WARMUP("field0", "return obj.field0")); | 190 CompileRun(FN_WARMUP("field0", "return obj.field0")); |
| 152 CompileRun(FN_WARMUP("field1", "return obj.field1")); | 191 CompileRun(FN_WARMUP("field1", "return obj.field1")); |
| 153 CompileRun(FN_WARMUP("field2", "return obj.field2")); | 192 CompileRun(FN_WARMUP("field2", "return obj.field2")); |
| 154 | 193 |
| 155 // Access fields. | 194 // Access fields. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 // Callbacks: | 416 // Callbacks: |
| 378 CompileRun(FN_WARMUP("callbackint", "return obj.int")); | 417 CompileRun(FN_WARMUP("callbackint", "return obj.int")); |
| 379 ExpectInt32("callbackint()", 12345); | 418 ExpectInt32("callbackint()", 12345); |
| 380 | 419 |
| 381 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); | 420 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); |
| 382 ExpectString("callbackstr()", kApiCallbackStringValue); | 421 ExpectString("callbackstr()", kApiCallbackStringValue); |
| 383 | 422 |
| 384 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); | 423 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); |
| 385 ExpectInt32("callbackparam()", 1000); | 424 ExpectInt32("callbackparam()", 1000); |
| 386 } | 425 } |
| OLD | NEW |