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 |