| 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 useUncheckedLoader) { |
| 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 (useUncheckedLoader) { |
| 122 builder->ReturnValue( |
| 123 builder->LoadInternalFieldUnchecked(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 void checkLoadInternalField(bool useUncheckedLoader, bool emitDebugChecks) { |
| 129 // "Fast" accessor that accesses an internal field. | |
| 130 TEST(FastAccessorWithInternalField) { | |
| 131 // Crankshaft support for fast accessors is not implemented; crankshafted | 135 // Crankshaft support for fast accessors is not implemented; crankshafted |
| 132 // code uses the slow accessor which breaks this test's expectations. | 136 // code uses the slow accessor which breaks this test's expectations. |
| 133 v8::internal::FLAG_always_opt = false; | 137 v8::internal::FLAG_always_opt = false; |
| 138 |
| 139 // De/activate debug checks. |
| 140 v8::internal::FLAG_debug_code = emitDebugChecks; |
| 134 LocalContext env; | 141 LocalContext env; |
| 135 v8::Isolate* isolate = env->GetIsolate(); | 142 v8::Isolate* isolate = env->GetIsolate(); |
| 136 v8::HandleScope scope(isolate); | 143 v8::HandleScope scope(isolate); |
| 137 | 144 |
| 138 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); | 145 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); |
| 139 foo->SetInternalFieldCount(3); | 146 foo->SetInternalFieldCount(3); |
| 140 AddInternalFieldAccessor(isolate, foo, "field0", 0); | 147 AddInternalFieldAccessor(isolate, foo, "field0", 0, useUncheckedLoader); |
| 141 AddInternalFieldAccessor(isolate, foo, "field1", 1); | 148 AddInternalFieldAccessor(isolate, foo, "field1", 1, useUncheckedLoader); |
| 142 AddInternalFieldAccessor(isolate, foo, "field2", 2); | 149 AddInternalFieldAccessor(isolate, foo, "field2", 2, useUncheckedLoader); |
| 143 | 150 |
| 144 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. | 151 // 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(); | 152 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); |
| 146 obj->SetInternalField(0, v8_str("Hi there!")); | 153 obj->SetInternalField(0, v8_str("Hi there!")); |
| 147 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); | 154 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); |
| 148 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); | 155 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); |
| 149 | 156 |
| 150 // Warmup. | 157 // Warmup. |
| 151 CompileRun(FN_WARMUP("field0", "return obj.field0")); | 158 CompileRun(FN_WARMUP("field0", "return obj.field0")); |
| 152 CompileRun(FN_WARMUP("field1", "return obj.field1")); | 159 CompileRun(FN_WARMUP("field1", "return obj.field1")); |
| 153 CompileRun(FN_WARMUP("field2", "return obj.field2")); | 160 CompileRun(FN_WARMUP("field2", "return obj.field2")); |
| 154 | 161 |
| 155 // Access fields. | 162 // Access fields. |
| 156 ExpectString("field0()", "Hi there!"); | 163 ExpectString("field0()", "Hi there!"); |
| 157 ExpectInt32("field1()", 4321); | 164 ExpectInt32("field1()", 4321); |
| 158 ExpectUndefined("field2()"); | 165 ExpectUndefined("field2()"); |
| 159 } | 166 } |
| 160 | 167 |
| 168 // "Fast" accessor that accesses an internal field. |
| 169 TEST(FastAccessorWithInternalField) { checkLoadInternalField(false, false); } |
| 170 |
| 171 // "Fast" accessor that accesses an internal field using the fast(er) |
| 172 // implementation of LoadInternalField. |
| 173 TEST(FastAccessorLoadInternalFieldUnchecked) { |
| 174 checkLoadInternalField(true, false); |
| 175 checkLoadInternalField(true, true); |
| 176 } |
| 161 | 177 |
| 162 // "Fast" accessor with control flow via ...OrReturnNull methods. | 178 // "Fast" accessor with control flow via ...OrReturnNull methods. |
| 163 TEST(FastAccessorOrReturnNull) { | 179 TEST(FastAccessorOrReturnNull) { |
| 164 // Crankshaft support for fast accessors is not implemented; crankshafted | 180 // Crankshaft support for fast accessors is not implemented; crankshafted |
| 165 // code uses the slow accessor which breaks this test's expectations. | 181 // code uses the slow accessor which breaks this test's expectations. |
| 166 v8::internal::FLAG_always_opt = false; | 182 v8::internal::FLAG_always_opt = false; |
| 167 LocalContext env; | 183 LocalContext env; |
| 168 v8::Isolate* isolate = env->GetIsolate(); | 184 v8::Isolate* isolate = env->GetIsolate(); |
| 169 v8::HandleScope scope(isolate); | 185 v8::HandleScope scope(isolate); |
| 170 | 186 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // Callbacks: | 393 // Callbacks: |
| 378 CompileRun(FN_WARMUP("callbackint", "return obj.int")); | 394 CompileRun(FN_WARMUP("callbackint", "return obj.int")); |
| 379 ExpectInt32("callbackint()", 12345); | 395 ExpectInt32("callbackint()", 12345); |
| 380 | 396 |
| 381 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); | 397 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); |
| 382 ExpectString("callbackstr()", kApiCallbackStringValue); | 398 ExpectString("callbackstr()", kApiCallbackStringValue); |
| 383 | 399 |
| 384 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); | 400 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); |
| 385 ExpectInt32("callbackparam()", 1000); | 401 ExpectInt32("callbackparam()", 1000); |
| 386 } | 402 } |
| OLD | NEW |