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

Side by Side Diff: test/cctest/test-api.cc

Issue 151603004: A64: Synchronize with r16587. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-circular-queue.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 134 }
135 135
136 136
137 static void ExpectUndefined(const char* code) { 137 static void ExpectUndefined(const char* code) {
138 Local<Value> result = CompileRun(code); 138 Local<Value> result = CompileRun(code);
139 CHECK(result->IsUndefined()); 139 CHECK(result->IsUndefined());
140 } 140 }
141 141
142 142
143 static int signature_callback_count; 143 static int signature_callback_count;
144 static Local<Value> signature_expected_receiver;
144 static void IncrementingSignatureCallback( 145 static void IncrementingSignatureCallback(
145 const v8::FunctionCallbackInfo<v8::Value>& args) { 146 const v8::FunctionCallbackInfo<v8::Value>& args) {
146 ApiTestFuzzer::Fuzz(); 147 ApiTestFuzzer::Fuzz();
147 signature_callback_count++; 148 signature_callback_count++;
149 CHECK_EQ(signature_expected_receiver, args.Holder());
150 CHECK_EQ(signature_expected_receiver, args.This());
148 v8::Handle<v8::Array> result = v8::Array::New(args.Length()); 151 v8::Handle<v8::Array> result = v8::Array::New(args.Length());
149 for (int i = 0; i < args.Length(); i++) 152 for (int i = 0; i < args.Length(); i++)
150 result->Set(v8::Integer::New(i), args[i]); 153 result->Set(v8::Integer::New(i), args[i]);
151 args.GetReturnValue().Set(result); 154 args.GetReturnValue().Set(result);
152 } 155 }
153 156
154 157
155 static void SignatureCallback( 158 static void SignatureCallback(
156 const v8::FunctionCallbackInfo<v8::Value>& args) { 159 const v8::FunctionCallbackInfo<v8::Value>& args) {
157 ApiTestFuzzer::Fuzz(); 160 ApiTestFuzzer::Fuzz();
158 v8::Handle<v8::Array> result = v8::Array::New(args.Length()); 161 v8::Handle<v8::Array> result = v8::Array::New(args.Length());
159 for (int i = 0; i < args.Length(); i++) { 162 for (int i = 0; i < args.Length(); i++) {
160 result->Set(v8::Integer::New(i), args[i]); 163 result->Set(v8::Integer::New(i), args[i]);
161 } 164 }
162 args.GetReturnValue().Set(result); 165 args.GetReturnValue().Set(result);
163 } 166 }
164 167
165 168
169 // Tests that call v8::V8::Dispose() cannot be threaded.
170 TEST(InitializeAndDisposeOnce) {
171 CHECK(v8::V8::Initialize());
172 CHECK(v8::V8::Dispose());
173 }
174
175
176 // Tests that call v8::V8::Dispose() cannot be threaded.
177 TEST(InitializeAndDisposeMultiple) {
178 for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
179 for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
180 for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
181 // TODO(mstarzinger): This should fail gracefully instead of asserting.
182 // for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
183 for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
184 }
185
186
166 THREADED_TEST(Handles) { 187 THREADED_TEST(Handles) {
167 v8::HandleScope scope(v8::Isolate::GetCurrent()); 188 v8::HandleScope scope(v8::Isolate::GetCurrent());
168 Local<Context> local_env; 189 Local<Context> local_env;
169 { 190 {
170 LocalContext env; 191 LocalContext env;
171 local_env = env.local(); 192 local_env = env.local();
172 } 193 }
173 194
174 // Local context should still be live. 195 // Local context should still be live.
175 CHECK(!local_env.IsEmpty()); 196 CHECK(!local_env.IsEmpty());
(...skipping 20 matching lines...) Expand all
196 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); 217 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
197 env->Enter(); 218 env->Enter();
198 CHECK(env->InContext()); 219 CHECK(env->InContext());
199 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); 220 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
200 env->Exit(); 221 env->Exit();
201 CHECK(!env->InContext()); 222 CHECK(!env->InContext());
202 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); 223 CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
203 } 224 }
204 225
205 226
227 static void TestSignature(const char* loop_js, Local<Value> receiver) {
228 i::ScopedVector<char> source(200);
229 i::OS::SNPrintF(source,
230 "for (var i = 0; i < 10; i++) {"
231 " %s"
232 "}",
233 loop_js);
234 signature_callback_count = 0;
235 signature_expected_receiver = receiver;
236 bool expected_to_throw = receiver.IsEmpty();
237 v8::TryCatch try_catch;
238 CompileRun(source.start());
239 CHECK_EQ(expected_to_throw, try_catch.HasCaught());
240 if (!expected_to_throw) {
241 CHECK_EQ(10, signature_callback_count);
242 } else {
243 CHECK_EQ(v8_str("TypeError: Illegal invocation"),
244 try_catch.Exception()->ToString());
245 }
246 }
247
248
206 THREADED_TEST(ReceiverSignature) { 249 THREADED_TEST(ReceiverSignature) {
207 LocalContext env; 250 LocalContext env;
208 v8::HandleScope scope(env->GetIsolate()); 251 v8::HandleScope scope(env->GetIsolate());
252 // Setup templates.
209 v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); 253 v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
210 v8::Handle<v8::Signature> sig = v8::Signature::New(fun); 254 v8::Handle<v8::Signature> sig = v8::Signature::New(fun);
211 fun->PrototypeTemplate()->Set( 255 v8::Handle<v8::FunctionTemplate> callback_sig =
212 v8_str("m"), 256 v8::FunctionTemplate::New(
213 v8::FunctionTemplate::New(IncrementingSignatureCallback, 257 IncrementingSignatureCallback, Local<Value>(), sig);
214 v8::Handle<Value>(), 258 v8::Handle<v8::FunctionTemplate> callback =
215 sig)); 259 v8::FunctionTemplate::New(IncrementingSignatureCallback);
216 env->Global()->Set(v8_str("Fun"), fun->GetFunction());
217 signature_callback_count = 0;
218 CompileRun(
219 "var o = new Fun();"
220 "o.m();");
221 CHECK_EQ(1, signature_callback_count);
222 v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(); 260 v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New();
223 sub_fun->Inherit(fun); 261 sub_fun->Inherit(fun);
224 env->Global()->Set(v8_str("SubFun"), sub_fun->GetFunction()); 262 v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New();
263 // Install properties.
264 v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate();
265 fun_proto->Set(v8_str("prop_sig"), callback_sig);
266 fun_proto->Set(v8_str("prop"), callback);
267 fun_proto->SetAccessorProperty(
268 v8_str("accessor_sig"), callback_sig, callback_sig);
269 fun_proto->SetAccessorProperty(v8_str("accessor"), callback, callback);
270 // Instantiate templates.
271 Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
272 Local<Value> sub_fun_instance = sub_fun->InstanceTemplate()->NewInstance();
273 // Setup global variables.
274 env->Global()->Set(v8_str("Fun"), fun->GetFunction());
275 env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction());
276 env->Global()->Set(v8_str("fun_instance"), fun_instance);
277 env->Global()->Set(v8_str("sub_fun_instance"), sub_fun_instance);
225 CompileRun( 278 CompileRun(
226 "var o = new SubFun();" 279 "var accessor_sig_key = 'accessor_sig';"
227 "o.m();"); 280 "var accessor_key = 'accessor';"
228 CHECK_EQ(2, signature_callback_count); 281 "var prop_sig_key = 'prop_sig';"
229 282 "var prop_key = 'prop';"
230 v8::TryCatch try_catch; 283 ""
231 CompileRun( 284 "function copy_props(obj) {"
232 "var o = { };" 285 " var keys = [accessor_sig_key, accessor_key, prop_sig_key, prop_key];"
233 "o.m = Fun.prototype.m;" 286 " var source = Fun.prototype;"
234 "o.m();"); 287 " for (var i in keys) {"
235 CHECK_EQ(2, signature_callback_count); 288 " var key = keys[i];"
236 CHECK(try_catch.HasCaught()); 289 " var desc = Object.getOwnPropertyDescriptor(source, key);"
237 try_catch.Reset(); 290 " Object.defineProperty(obj, key, desc);"
238 v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New(); 291 " }"
239 sub_fun->Inherit(fun); 292 "}"
240 env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction()); 293 ""
241 CompileRun( 294 "var obj = {};"
242 "var o = new UnrelFun();" 295 "copy_props(obj);"
243 "o.m = Fun.prototype.m;" 296 "var unrel = new UnrelFun();"
244 "o.m();"); 297 "copy_props(unrel);");
245 CHECK_EQ(2, signature_callback_count); 298 // Test with and without ICs
246 CHECK(try_catch.HasCaught()); 299 const char* test_objects[] = {
300 "fun_instance", "sub_fun_instance", "obj", "unrel" };
301 unsigned bad_signature_start_offset = 2;
302 for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
303 i::ScopedVector<char> source(200);
304 i::OS::SNPrintF(
305 source, "var test_object = %s; test_object", test_objects[i]);
306 Local<Value> test_object = CompileRun(source.start());
307 TestSignature("test_object.prop();", test_object);
308 TestSignature("test_object.accessor;", test_object);
309 TestSignature("test_object[accessor_key];", test_object);
310 TestSignature("test_object.accessor = 1;", test_object);
311 TestSignature("test_object[accessor_key] = 1;", test_object);
312 if (i >= bad_signature_start_offset) test_object = Local<Value>();
313 TestSignature("test_object.prop_sig();", test_object);
314 TestSignature("test_object.accessor_sig;", test_object);
315 TestSignature("test_object[accessor_sig_key];", test_object);
316 TestSignature("test_object.accessor_sig = 1;", test_object);
317 TestSignature("test_object[accessor_sig_key] = 1;", test_object);
318 }
247 } 319 }
248 320
249 321
250 THREADED_TEST(ArgumentSignature) { 322 THREADED_TEST(ArgumentSignature) {
251 LocalContext env; 323 LocalContext env;
252 v8::HandleScope scope(env->GetIsolate()); 324 v8::HandleScope scope(env->GetIsolate());
253 v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New(); 325 v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New();
254 cons->SetClassName(v8_str("Cons")); 326 cons->SetClassName(v8_str("Cons"));
255 v8::Handle<v8::Signature> sig = 327 v8::Handle<v8::Signature> sig =
256 v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 1, &cons); 328 v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 1, &cons);
(...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 for (i = 0; name_str[i] && prefix[i]; ++i) { 1893 for (i = 0; name_str[i] && prefix[i]; ++i) {
1822 if (name_str[i] != prefix[i]) return; 1894 if (name_str[i] != prefix[i]) return;
1823 } 1895 }
1824 Handle<Object> self = info.This(); 1896 Handle<Object> self = info.This();
1825 info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i))); 1897 info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i)));
1826 } 1898 }
1827 1899
1828 void InterceptorSetter(Local<String> name, 1900 void InterceptorSetter(Local<String> name,
1829 Local<Value> value, 1901 Local<Value> value,
1830 const v8::PropertyCallbackInfo<v8::Value>& info) { 1902 const v8::PropertyCallbackInfo<v8::Value>& info) {
1831 // Intercept accesses that set certain integer values. 1903 // Intercept accesses that set certain integer values, for which the name does
1904 // not start with 'accessor_'.
1905 String::Utf8Value utf8(name);
1906 char* name_str = *utf8;
1907 char prefix[] = "accessor_";
1908 int i;
1909 for (i = 0; name_str[i] && prefix[i]; ++i) {
1910 if (name_str[i] != prefix[i]) break;
1911 }
1912 if (!prefix[i]) return;
1913
1832 if (value->IsInt32() && value->Int32Value() < 10000) { 1914 if (value->IsInt32() && value->Int32Value() < 10000) {
1833 Handle<Object> self = info.This(); 1915 Handle<Object> self = info.This();
1834 self->SetHiddenValue(name, value); 1916 self->SetHiddenValue(name, value);
1835 info.GetReturnValue().Set(value); 1917 info.GetReturnValue().Set(value);
1836 } 1918 }
1837 } 1919 }
1838 1920
1839 void AddAccessor(Handle<FunctionTemplate> templ, 1921 void AddAccessor(Handle<FunctionTemplate> templ,
1840 Handle<String> name, 1922 Handle<String> name,
1841 v8::AccessorGetterCallback getter, 1923 v8::AccessorGetterCallback getter,
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 } 3183 }
3102 { 3184 {
3103 v8::HandleScope scope(isolate); 3185 v8::HandleScope scope(isolate);
3104 global.Reset(isolate, v8_str("longer")); 3186 global.Reset(isolate, v8_str("longer"));
3105 } 3187 }
3106 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count); 3188 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count);
3107 { 3189 {
3108 v8::HandleScope scope(isolate); 3190 v8::HandleScope scope(isolate);
3109 CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6); 3191 CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6);
3110 } 3192 }
3111 global.Dispose(isolate); 3193 global.Dispose();
3112 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1); 3194 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1);
3113 } 3195 }
3114 3196
3115 3197
3116 THREADED_TEST(ResettingGlobalHandleToEmpty) { 3198 THREADED_TEST(ResettingGlobalHandleToEmpty) {
3117 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 3199 v8::Isolate* isolate = v8::Isolate::GetCurrent();
3118 v8::Persistent<String> global; 3200 v8::Persistent<String> global;
3119 { 3201 {
3120 v8::HandleScope scope(isolate); 3202 v8::HandleScope scope(isolate);
3121 global.Reset(isolate, v8_str("str")); 3203 global.Reset(isolate, v8_str("str"));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 int id_; 3317 int id_;
3236 int number_of_weak_calls_; 3318 int number_of_weak_calls_;
3237 }; 3319 };
3238 3320
3239 3321
3240 static void WeakPointerCallback(v8::Isolate* isolate, 3322 static void WeakPointerCallback(v8::Isolate* isolate,
3241 Persistent<Value>* handle, 3323 Persistent<Value>* handle,
3242 WeakCallCounter* counter) { 3324 WeakCallCounter* counter) {
3243 CHECK_EQ(1234, counter->id()); 3325 CHECK_EQ(1234, counter->id());
3244 counter->increment(); 3326 counter->increment();
3245 handle->Dispose(isolate); 3327 handle->Dispose();
3246 } 3328 }
3247 3329
3248 3330
3249 static UniqueId MakeUniqueId(const Persistent<Value>& p) { 3331 static UniqueId MakeUniqueId(const Persistent<Value>& p) {
3250 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); 3332 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
3251 } 3333 }
3252 3334
3253 3335
3254 THREADED_TEST(ApiObjectGroups) { 3336 THREADED_TEST(ApiObjectGroups) {
3255 LocalContext env; 3337 LocalContext env;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3308 iso)->heap(); 3390 iso)->heap();
3309 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3391 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3310 3392
3311 // All object should be alive. 3393 // All object should be alive.
3312 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3394 CHECK_EQ(0, counter.NumberOfWeakCalls());
3313 3395
3314 // Weaken the root. 3396 // Weaken the root.
3315 root.MakeWeak(&counter, &WeakPointerCallback); 3397 root.MakeWeak(&counter, &WeakPointerCallback);
3316 // But make children strong roots---all the objects (except for children) 3398 // But make children strong roots---all the objects (except for children)
3317 // should be collectable now. 3399 // should be collectable now.
3318 g1c1.ClearWeak(iso); 3400 g1c1.ClearWeak();
3319 g2c1.ClearWeak(iso); 3401 g2c1.ClearWeak();
3320 3402
3321 // Groups are deleted, rebuild groups. 3403 // Groups are deleted, rebuild groups.
3322 { 3404 {
3323 UniqueId id1 = MakeUniqueId(g1s1); 3405 UniqueId id1 = MakeUniqueId(g1s1);
3324 UniqueId id2 = MakeUniqueId(g2s2); 3406 UniqueId id2 = MakeUniqueId(g2s2);
3325 iso->SetObjectGroupId(g1s1, id1); 3407 iso->SetObjectGroupId(g1s1, id1);
3326 iso->SetObjectGroupId(g1s2, id1); 3408 iso->SetObjectGroupId(g1s2, id1);
3327 iso->SetReferenceFromGroup(id1, g1c1); 3409 iso->SetReferenceFromGroup(id1, g1c1);
3328 iso->SetObjectGroupId(g2s1, id2); 3410 iso->SetObjectGroupId(g2s1, id2);
3329 iso->SetObjectGroupId(g2s2, id2); 3411 iso->SetObjectGroupId(g2s2, id2);
(...skipping 29 matching lines...) Expand all
3359 Persistent<Value> g3s2; 3441 Persistent<Value> g3s2;
3360 Persistent<Value> g4s1; 3442 Persistent<Value> g4s1;
3361 Persistent<Value> g4s2; 3443 Persistent<Value> g4s2;
3362 3444
3363 { 3445 {
3364 HandleScope scope(iso); 3446 HandleScope scope(iso);
3365 g1s1.Reset(iso, Object::New()); 3447 g1s1.Reset(iso, Object::New());
3366 g1s2.Reset(iso, Object::New()); 3448 g1s2.Reset(iso, Object::New());
3367 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3449 g1s1.MakeWeak(&counter, &WeakPointerCallback);
3368 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3450 g1s2.MakeWeak(&counter, &WeakPointerCallback);
3369 CHECK(g1s1.IsWeak(iso)); 3451 CHECK(g1s1.IsWeak());
3370 CHECK(g1s2.IsWeak(iso)); 3452 CHECK(g1s2.IsWeak());
3371 3453
3372 g2s1.Reset(iso, Object::New()); 3454 g2s1.Reset(iso, Object::New());
3373 g2s2.Reset(iso, Object::New()); 3455 g2s2.Reset(iso, Object::New());
3374 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3456 g2s1.MakeWeak(&counter, &WeakPointerCallback);
3375 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3457 g2s2.MakeWeak(&counter, &WeakPointerCallback);
3376 CHECK(g2s1.IsWeak(iso)); 3458 CHECK(g2s1.IsWeak());
3377 CHECK(g2s2.IsWeak(iso)); 3459 CHECK(g2s2.IsWeak());
3378 3460
3379 g3s1.Reset(iso, Object::New()); 3461 g3s1.Reset(iso, Object::New());
3380 g3s2.Reset(iso, Object::New()); 3462 g3s2.Reset(iso, Object::New());
3381 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3463 g3s1.MakeWeak(&counter, &WeakPointerCallback);
3382 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3464 g3s2.MakeWeak(&counter, &WeakPointerCallback);
3383 CHECK(g3s1.IsWeak(iso)); 3465 CHECK(g3s1.IsWeak());
3384 CHECK(g3s2.IsWeak(iso)); 3466 CHECK(g3s2.IsWeak());
3385 3467
3386 g4s1.Reset(iso, Object::New()); 3468 g4s1.Reset(iso, Object::New());
3387 g4s2.Reset(iso, Object::New()); 3469 g4s2.Reset(iso, Object::New());
3388 g4s1.MakeWeak(&counter, &WeakPointerCallback); 3470 g4s1.MakeWeak(&counter, &WeakPointerCallback);
3389 g4s2.MakeWeak(&counter, &WeakPointerCallback); 3471 g4s2.MakeWeak(&counter, &WeakPointerCallback);
3390 CHECK(g4s1.IsWeak(iso)); 3472 CHECK(g4s1.IsWeak());
3391 CHECK(g4s2.IsWeak(iso)); 3473 CHECK(g4s2.IsWeak());
3392 } 3474 }
3393 3475
3394 Persistent<Value> root(iso, g1s1); // make a root. 3476 Persistent<Value> root(iso, g1s1); // make a root.
3395 3477
3396 // Connect groups. We're building the following cycle: 3478 // Connect groups. We're building the following cycle:
3397 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3479 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3398 // groups. 3480 // groups.
3399 { 3481 {
3400 UniqueId id1 = MakeUniqueId(g1s1); 3482 UniqueId id1 = MakeUniqueId(g1s1);
3401 UniqueId id2 = MakeUniqueId(g2s1); 3483 UniqueId id2 = MakeUniqueId(g2s1);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3565 g2s2.MakeWeak(&counter, &WeakPointerCallback);
3484 3566
3485 g3s1.Reset(iso, Object::New()); 3567 g3s1.Reset(iso, Object::New());
3486 g3s2.Reset(iso, Object::New()); 3568 g3s2.Reset(iso, Object::New());
3487 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3569 g3s1.MakeWeak(&counter, &WeakPointerCallback);
3488 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3570 g3s2.MakeWeak(&counter, &WeakPointerCallback);
3489 } 3571 }
3490 3572
3491 // Make a root. 3573 // Make a root.
3492 Persistent<Value> root(iso, g1s1); 3574 Persistent<Value> root(iso, g1s1);
3493 root.MarkPartiallyDependent(iso); 3575 root.MarkPartiallyDependent();
3494 3576
3495 // Connect groups. We're building the following cycle: 3577 // Connect groups. We're building the following cycle:
3496 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3578 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3497 // groups. 3579 // groups.
3498 { 3580 {
3499 HandleScope handle_scope(iso); 3581 HandleScope handle_scope(iso);
3500 g1s1.MarkPartiallyDependent(iso); 3582 g1s1.MarkPartiallyDependent();
3501 g1s2.MarkPartiallyDependent(iso); 3583 g1s2.MarkPartiallyDependent();
3502 g2s1.MarkPartiallyDependent(iso); 3584 g2s1.MarkPartiallyDependent();
3503 g2s2.MarkPartiallyDependent(iso); 3585 g2s2.MarkPartiallyDependent();
3504 g3s1.MarkPartiallyDependent(iso); 3586 g3s1.MarkPartiallyDependent();
3505 g3s2.MarkPartiallyDependent(iso); 3587 g3s2.MarkPartiallyDependent();
3506 iso->SetObjectGroupId(g1s1, UniqueId(1)); 3588 iso->SetObjectGroupId(g1s1, UniqueId(1));
3507 iso->SetObjectGroupId(g1s2, UniqueId(1)); 3589 iso->SetObjectGroupId(g1s2, UniqueId(1));
3508 Local<Object>::New(iso, g1s1.As<Object>())->Set( 3590 Local<Object>::New(iso, g1s1.As<Object>())->Set(
3509 v8_str("x"), Local<Value>::New(iso, g2s1)); 3591 v8_str("x"), Local<Value>::New(iso, g2s1));
3510 iso->SetObjectGroupId(g2s1, UniqueId(2)); 3592 iso->SetObjectGroupId(g2s1, UniqueId(2));
3511 iso->SetObjectGroupId(g2s2, UniqueId(2)); 3593 iso->SetObjectGroupId(g2s2, UniqueId(2));
3512 Local<Object>::New(iso, g2s1.As<Object>())->Set( 3594 Local<Object>::New(iso, g2s1.As<Object>())->Set(
3513 v8_str("x"), Local<Value>::New(iso, g3s1)); 3595 v8_str("x"), Local<Value>::New(iso, g3s1));
3514 iso->SetObjectGroupId(g3s1, UniqueId(3)); 3596 iso->SetObjectGroupId(g3s1, UniqueId(3));
3515 iso->SetObjectGroupId(g3s2, UniqueId(3)); 3597 iso->SetObjectGroupId(g3s2, UniqueId(3));
3516 Local<Object>::New(iso, g3s1.As<Object>())->Set( 3598 Local<Object>::New(iso, g3s1.As<Object>())->Set(
3517 v8_str("x"), Local<Value>::New(iso, g1s1)); 3599 v8_str("x"), Local<Value>::New(iso, g1s1));
3518 } 3600 }
3519 3601
3520 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3602 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3521 iso)->heap(); 3603 iso)->heap();
3522 heap->CollectGarbage(i::NEW_SPACE); 3604 heap->CollectGarbage(i::NEW_SPACE);
3523 3605
3524 // All objects should be alive. 3606 // All objects should be alive.
3525 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3607 CHECK_EQ(0, counter.NumberOfWeakCalls());
3526 3608
3527 // Weaken the root. 3609 // Weaken the root.
3528 root.MakeWeak(&counter, &WeakPointerCallback); 3610 root.MakeWeak(&counter, &WeakPointerCallback);
3529 root.MarkPartiallyDependent(iso); 3611 root.MarkPartiallyDependent();
3530 3612
3531 v8::Isolate* isolate = v8::Isolate::GetCurrent();
3532 // Groups are deleted, rebuild groups. 3613 // Groups are deleted, rebuild groups.
3533 { 3614 {
3534 HandleScope handle_scope(iso); 3615 HandleScope handle_scope(iso);
3535 g1s1.MarkPartiallyDependent(isolate); 3616 g1s1.MarkPartiallyDependent();
3536 g1s2.MarkPartiallyDependent(isolate); 3617 g1s2.MarkPartiallyDependent();
3537 g2s1.MarkPartiallyDependent(isolate); 3618 g2s1.MarkPartiallyDependent();
3538 g2s2.MarkPartiallyDependent(isolate); 3619 g2s2.MarkPartiallyDependent();
3539 g3s1.MarkPartiallyDependent(isolate); 3620 g3s1.MarkPartiallyDependent();
3540 g3s2.MarkPartiallyDependent(isolate); 3621 g3s2.MarkPartiallyDependent();
3541 iso->SetObjectGroupId(g1s1, UniqueId(1)); 3622 iso->SetObjectGroupId(g1s1, UniqueId(1));
3542 iso->SetObjectGroupId(g1s2, UniqueId(1)); 3623 iso->SetObjectGroupId(g1s2, UniqueId(1));
3543 Local<Object>::New(iso, g1s1.As<Object>())->Set( 3624 Local<Object>::New(iso, g1s1.As<Object>())->Set(
3544 v8_str("x"), Local<Value>::New(iso, g2s1)); 3625 v8_str("x"), Local<Value>::New(iso, g2s1));
3545 iso->SetObjectGroupId(g2s1, UniqueId(2)); 3626 iso->SetObjectGroupId(g2s1, UniqueId(2));
3546 iso->SetObjectGroupId(g2s2, UniqueId(2)); 3627 iso->SetObjectGroupId(g2s2, UniqueId(2));
3547 Local<Object>::New(iso, g2s1.As<Object>())->Set( 3628 Local<Object>::New(iso, g2s1.As<Object>())->Set(
3548 v8_str("x"), Local<Value>::New(iso, g3s1)); 3629 v8_str("x"), Local<Value>::New(iso, g3s1));
3549 iso->SetObjectGroupId(g3s1, UniqueId(3)); 3630 iso->SetObjectGroupId(g3s1, UniqueId(3));
3550 iso->SetObjectGroupId(g3s2, UniqueId(3)); 3631 iso->SetObjectGroupId(g3s2, UniqueId(3));
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4888 CHECK(!v8_num(1)->StrictEquals(v8_num(2))); 4969 CHECK(!v8_num(1)->StrictEquals(v8_num(2)));
4889 CHECK(v8_num(0)->StrictEquals(v8_num(-0))); 4970 CHECK(v8_num(0)->StrictEquals(v8_num(-0)));
4890 Local<Value> not_a_number = v8_num(i::OS::nan_value()); 4971 Local<Value> not_a_number = v8_num(i::OS::nan_value());
4891 CHECK(!not_a_number->StrictEquals(not_a_number)); 4972 CHECK(!not_a_number->StrictEquals(not_a_number));
4892 CHECK(v8::False()->StrictEquals(v8::False())); 4973 CHECK(v8::False()->StrictEquals(v8::False()));
4893 CHECK(!v8::False()->StrictEquals(v8::Undefined())); 4974 CHECK(!v8::False()->StrictEquals(v8::Undefined()));
4894 4975
4895 v8::Handle<v8::Object> obj = v8::Object::New(); 4976 v8::Handle<v8::Object> obj = v8::Object::New();
4896 v8::Persistent<v8::Object> alias(isolate, obj); 4977 v8::Persistent<v8::Object> alias(isolate, obj);
4897 CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj)); 4978 CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
4898 alias.Dispose(isolate); 4979 alias.Dispose();
4899 } 4980 }
4900 4981
4901 4982
4902 THREADED_TEST(MultiRun) { 4983 THREADED_TEST(MultiRun) {
4903 LocalContext context; 4984 LocalContext context;
4904 v8::HandleScope scope(context->GetIsolate()); 4985 v8::HandleScope scope(context->GetIsolate());
4905 Local<Script> script = Script::Compile(v8_str("x")); 4986 Local<Script> script = Script::Compile(v8_str("x"));
4906 for (int i = 0; i < 10; i++) 4987 for (int i = 0; i < 10; i++)
4907 script->Run(); 4988 script->Run();
4908 } 4989 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
5203 v8::HandleScope scope(v8::Isolate::GetCurrent()); 5284 v8::HandleScope scope(v8::Isolate::GetCurrent());
5204 Local<ObjectTemplate> templ = ObjectTemplate::New(); 5285 Local<ObjectTemplate> templ = ObjectTemplate::New();
5205 templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut")); 5286 templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut"));
5206 LocalContext context; 5287 LocalContext context;
5207 context->Global()->Set(v8_str("obj"), templ->NewInstance()); 5288 context->Global()->Set(v8_str("obj"), templ->NewInstance());
5208 Local<Script> script = Script::Compile(v8_str("obj.x = 4")); 5289 Local<Script> script = Script::Compile(v8_str("obj.x = 4"));
5209 for (int i = 0; i < 10; i++) { 5290 for (int i = 0; i < 10; i++) {
5210 CHECK(xValue.IsEmpty()); 5291 CHECK(xValue.IsEmpty());
5211 script->Run(); 5292 script->Run();
5212 CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue)); 5293 CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
5213 xValue.Dispose(context->GetIsolate()); 5294 xValue.Dispose();
5214 xValue.Clear(); 5295 xValue.Clear();
5215 } 5296 }
5216 } 5297 }
5217 5298
5218 5299
5219 THREADED_TEST(SetterOnly) { 5300 THREADED_TEST(SetterOnly) {
5220 v8::HandleScope scope(v8::Isolate::GetCurrent()); 5301 v8::HandleScope scope(v8::Isolate::GetCurrent());
5221 Local<ObjectTemplate> templ = ObjectTemplate::New(); 5302 Local<ObjectTemplate> templ = ObjectTemplate::New();
5222 templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut")); 5303 templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut"));
5223 LocalContext context; 5304 LocalContext context;
5224 context->Global()->Set(v8_str("obj"), templ->NewInstance()); 5305 context->Global()->Set(v8_str("obj"), templ->NewInstance());
5225 Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x")); 5306 Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
5226 for (int i = 0; i < 10; i++) { 5307 for (int i = 0; i < 10; i++) {
5227 CHECK(xValue.IsEmpty()); 5308 CHECK(xValue.IsEmpty());
5228 script->Run(); 5309 script->Run();
5229 CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue)); 5310 CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
5230 xValue.Dispose(context->GetIsolate()); 5311 xValue.Dispose();
5231 xValue.Clear(); 5312 xValue.Clear();
5232 } 5313 }
5233 } 5314 }
5234 5315
5235 5316
5236 THREADED_TEST(NoAccessors) { 5317 THREADED_TEST(NoAccessors) {
5237 v8::HandleScope scope(v8::Isolate::GetCurrent()); 5318 v8::HandleScope scope(v8::Isolate::GetCurrent());
5238 Local<ObjectTemplate> templ = ObjectTemplate::New(); 5319 Local<ObjectTemplate> templ = ObjectTemplate::New();
5239 templ->SetAccessor(v8_str("x"), 5320 templ->SetAccessor(v8_str("x"),
5240 static_cast<v8::AccessorGetterCallback>(NULL), 5321 static_cast<v8::AccessorGetterCallback>(NULL),
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after
6595 6676
6596 class Snorkel { 6677 class Snorkel {
6597 public: 6678 public:
6598 Snorkel() { index_ = global_index++; } 6679 Snorkel() { index_ = global_index++; }
6599 int index_; 6680 int index_;
6600 }; 6681 };
6601 6682
6602 class Whammy { 6683 class Whammy {
6603 public: 6684 public:
6604 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } 6685 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
6605 ~Whammy() { script_.Dispose(isolate_); } 6686 ~Whammy() { script_.Dispose(); }
6606 v8::Handle<Script> getScript() { 6687 v8::Handle<Script> getScript() {
6607 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); 6688 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
6608 return Local<Script>::New(isolate_, script_); 6689 return Local<Script>::New(isolate_, script_);
6609 } 6690 }
6610 6691
6611 public: 6692 public:
6612 static const int kObjectCount = 256; 6693 static const int kObjectCount = 256;
6613 int cursor_; 6694 int cursor_;
6614 v8::Isolate* isolate_; 6695 v8::Isolate* isolate_;
6615 v8::Persistent<v8::Object> objects_[kObjectCount]; 6696 v8::Persistent<v8::Object> objects_[kObjectCount];
6616 v8::Persistent<Script> script_; 6697 v8::Persistent<Script> script_;
6617 }; 6698 };
6618 6699
6619 static void HandleWeakReference(v8::Isolate* isolate, 6700 static void HandleWeakReference(v8::Isolate* isolate,
6620 v8::Persistent<v8::Value>* obj, 6701 v8::Persistent<v8::Value>* obj,
6621 Snorkel* snorkel) { 6702 Snorkel* snorkel) {
6622 delete snorkel; 6703 delete snorkel;
6623 obj->ClearWeak(isolate); 6704 obj->ClearWeak();
6624 } 6705 }
6625 6706
6626 void WhammyPropertyGetter(Local<String> name, 6707 void WhammyPropertyGetter(Local<String> name,
6627 const v8::PropertyCallbackInfo<v8::Value>& info) { 6708 const v8::PropertyCallbackInfo<v8::Value>& info) {
6628 Whammy* whammy = 6709 Whammy* whammy =
6629 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); 6710 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
6630 6711
6631 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; 6712 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
6632 6713
6633 v8::Handle<v8::Object> obj = v8::Object::New(); 6714 v8::Handle<v8::Object> obj = v8::Object::New();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6669 "4"; 6750 "4";
6670 v8::Handle<Value> result = CompileRun(code); 6751 v8::Handle<Value> result = CompileRun(code);
6671 CHECK_EQ(4.0, result->NumberValue()); 6752 CHECK_EQ(4.0, result->NumberValue());
6672 delete whammy; 6753 delete whammy;
6673 } 6754 }
6674 6755
6675 6756
6676 static void DisposeAndSetFlag(v8::Isolate* isolate, 6757 static void DisposeAndSetFlag(v8::Isolate* isolate,
6677 v8::Persistent<v8::Object>* obj, 6758 v8::Persistent<v8::Object>* obj,
6678 bool* data) { 6759 bool* data) {
6679 obj->Dispose(isolate); 6760 obj->Dispose();
6680 *(data) = true; 6761 *(data) = true;
6681 } 6762 }
6682 6763
6683 6764
6684 THREADED_TEST(IndependentWeakHandle) { 6765 THREADED_TEST(IndependentWeakHandle) {
6685 v8::Isolate* iso = v8::Isolate::GetCurrent(); 6766 v8::Isolate* iso = v8::Isolate::GetCurrent();
6686 v8::HandleScope scope(iso); 6767 v8::HandleScope scope(iso);
6687 v8::Handle<Context> context = Context::New(iso); 6768 v8::Handle<Context> context = Context::New(iso);
6688 Context::Scope context_scope(context); 6769 Context::Scope context_scope(context);
6689 6770
6690 v8::Persistent<v8::Object> object_a, object_b; 6771 v8::Persistent<v8::Object> object_a, object_b;
6691 6772
6692 { 6773 {
6693 v8::HandleScope handle_scope(iso); 6774 v8::HandleScope handle_scope(iso);
6694 object_a.Reset(iso, v8::Object::New()); 6775 object_a.Reset(iso, v8::Object::New());
6695 object_b.Reset(iso, v8::Object::New()); 6776 object_b.Reset(iso, v8::Object::New());
6696 } 6777 }
6697 6778
6698 bool object_a_disposed = false; 6779 bool object_a_disposed = false;
6699 bool object_b_disposed = false; 6780 bool object_b_disposed = false;
6700 object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); 6781 object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
6701 object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag); 6782 object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
6702 CHECK(!object_b.IsIndependent(iso)); 6783 CHECK(!object_b.IsIndependent());
6703 object_a.MarkIndependent(iso); 6784 object_a.MarkIndependent();
6704 object_b.MarkIndependent(iso); 6785 object_b.MarkIndependent();
6705 CHECK(object_b.IsIndependent(iso)); 6786 CHECK(object_b.IsIndependent());
6706 HEAP->PerformScavenge(); 6787 HEAP->PerformScavenge();
6707 CHECK(object_a_disposed); 6788 CHECK(object_a_disposed);
6708 CHECK(object_b_disposed); 6789 CHECK(object_b_disposed);
6709 } 6790 }
6710 6791
6711 6792
6712 static void InvokeScavenge() { 6793 static void InvokeScavenge() {
6713 HEAP->PerformScavenge(); 6794 HEAP->PerformScavenge();
6714 } 6795 }
6715 6796
6716 6797
6717 static void InvokeMarkSweep() { 6798 static void InvokeMarkSweep() {
6718 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 6799 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
6719 } 6800 }
6720 6801
6721 6802
6722 static void ForceScavenge(v8::Isolate* isolate, 6803 static void ForceScavenge(v8::Isolate* isolate,
6723 v8::Persistent<v8::Object>* obj, 6804 v8::Persistent<v8::Object>* obj,
6724 bool* data) { 6805 bool* data) {
6725 obj->Dispose(isolate); 6806 obj->Dispose();
6726 *(data) = true; 6807 *(data) = true;
6727 InvokeScavenge(); 6808 InvokeScavenge();
6728 } 6809 }
6729 6810
6730 6811
6731 static void ForceMarkSweep(v8::Isolate* isolate, 6812 static void ForceMarkSweep(v8::Isolate* isolate,
6732 v8::Persistent<v8::Object>* obj, 6813 v8::Persistent<v8::Object>* obj,
6733 bool* data) { 6814 bool* data) {
6734 obj->Dispose(isolate); 6815 obj->Dispose();
6735 *(data) = true; 6816 *(data) = true;
6736 InvokeMarkSweep(); 6817 InvokeMarkSweep();
6737 } 6818 }
6738 6819
6739 6820
6740 THREADED_TEST(GCFromWeakCallbacks) { 6821 THREADED_TEST(GCFromWeakCallbacks) {
6741 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 6822 v8::Isolate* isolate = v8::Isolate::GetCurrent();
6742 v8::HandleScope scope(isolate); 6823 v8::HandleScope scope(isolate);
6743 v8::Handle<Context> context = Context::New(isolate); 6824 v8::Handle<Context> context = Context::New(isolate);
6744 Context::Scope context_scope(context); 6825 Context::Scope context_scope(context);
6745 6826
6746 static const int kNumberOfGCTypes = 2; 6827 static const int kNumberOfGCTypes = 2;
6747 typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback; 6828 typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback;
6748 Callback gc_forcing_callback[kNumberOfGCTypes] = 6829 Callback gc_forcing_callback[kNumberOfGCTypes] =
6749 {&ForceScavenge, &ForceMarkSweep}; 6830 {&ForceScavenge, &ForceMarkSweep};
6750 6831
6751 typedef void (*GCInvoker)(); 6832 typedef void (*GCInvoker)();
6752 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; 6833 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep};
6753 6834
6754 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { 6835 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
6755 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { 6836 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
6756 v8::Persistent<v8::Object> object; 6837 v8::Persistent<v8::Object> object;
6757 { 6838 {
6758 v8::HandleScope handle_scope(isolate); 6839 v8::HandleScope handle_scope(isolate);
6759 object.Reset(isolate, v8::Object::New()); 6840 object.Reset(isolate, v8::Object::New());
6760 } 6841 }
6761 bool disposed = false; 6842 bool disposed = false;
6762 object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); 6843 object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
6763 object.MarkIndependent(isolate); 6844 object.MarkIndependent();
6764 invoke_gc[outer_gc](); 6845 invoke_gc[outer_gc]();
6765 CHECK(disposed); 6846 CHECK(disposed);
6766 } 6847 }
6767 } 6848 }
6768 } 6849 }
6769 6850
6770 6851
6771 static void RevivingCallback(v8::Isolate* isolate, 6852 static void RevivingCallback(v8::Isolate* isolate,
6772 v8::Persistent<v8::Object>* obj, 6853 v8::Persistent<v8::Object>* obj,
6773 bool* data) { 6854 bool* data) {
6774 obj->ClearWeak(isolate); 6855 obj->ClearWeak();
6775 *(data) = true; 6856 *(data) = true;
6776 } 6857 }
6777 6858
6778 6859
6779 THREADED_TEST(IndependentHandleRevival) { 6860 THREADED_TEST(IndependentHandleRevival) {
6780 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 6861 v8::Isolate* isolate = v8::Isolate::GetCurrent();
6781 v8::HandleScope scope(isolate); 6862 v8::HandleScope scope(isolate);
6782 v8::Handle<Context> context = Context::New(isolate); 6863 v8::Handle<Context> context = Context::New(isolate);
6783 Context::Scope context_scope(context); 6864 Context::Scope context_scope(context);
6784 6865
6785 v8::Persistent<v8::Object> object; 6866 v8::Persistent<v8::Object> object;
6786 { 6867 {
6787 v8::HandleScope handle_scope(isolate); 6868 v8::HandleScope handle_scope(isolate);
6788 v8::Local<v8::Object> o = v8::Object::New(); 6869 v8::Local<v8::Object> o = v8::Object::New();
6789 object.Reset(isolate, o); 6870 object.Reset(isolate, o);
6790 o->Set(v8_str("x"), v8::Integer::New(1)); 6871 o->Set(v8_str("x"), v8::Integer::New(1));
6791 v8::Local<String> y_str = v8_str("y"); 6872 v8::Local<String> y_str = v8_str("y");
6792 o->Set(y_str, y_str); 6873 o->Set(y_str, y_str);
6793 } 6874 }
6794 bool revived = false; 6875 bool revived = false;
6795 object.MakeWeak(&revived, &RevivingCallback); 6876 object.MakeWeak(&revived, &RevivingCallback);
6796 object.MarkIndependent(isolate); 6877 object.MarkIndependent();
6797 HEAP->PerformScavenge(); 6878 HEAP->PerformScavenge();
6798 CHECK(revived); 6879 CHECK(revived);
6799 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 6880 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
6800 { 6881 {
6801 v8::HandleScope handle_scope(isolate); 6882 v8::HandleScope handle_scope(isolate);
6802 v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object); 6883 v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object);
6803 v8::Local<String> y_str = v8_str("y"); 6884 v8::Local<String> y_str = v8_str("y");
6804 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x"))); 6885 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x")));
6805 CHECK(o->Get(y_str)->Equals(y_str)); 6886 CHECK(o->Get(y_str)->Equals(y_str));
6806 } 6887 }
(...skipping 5784 matching lines...) Expand 10 before | Expand all | Expand 10 after
12591 12672
12592 12673
12593 v8::Persistent<v8::Object> some_object; 12674 v8::Persistent<v8::Object> some_object;
12594 v8::Persistent<v8::Object> bad_handle; 12675 v8::Persistent<v8::Object> bad_handle;
12595 12676
12596 void NewPersistentHandleCallback(v8::Isolate* isolate, 12677 void NewPersistentHandleCallback(v8::Isolate* isolate,
12597 v8::Persistent<v8::Value>* handle, 12678 v8::Persistent<v8::Value>* handle,
12598 void*) { 12679 void*) {
12599 v8::HandleScope scope(isolate); 12680 v8::HandleScope scope(isolate);
12600 bad_handle.Reset(isolate, some_object); 12681 bad_handle.Reset(isolate, some_object);
12601 handle->Dispose(isolate); 12682 handle->Dispose();
12602 } 12683 }
12603 12684
12604 12685
12605 THREADED_TEST(NewPersistentHandleFromWeakCallback) { 12686 THREADED_TEST(NewPersistentHandleFromWeakCallback) {
12606 LocalContext context; 12687 LocalContext context;
12607 v8::Isolate* isolate = context->GetIsolate(); 12688 v8::Isolate* isolate = context->GetIsolate();
12608 12689
12609 v8::Persistent<v8::Object> handle1, handle2; 12690 v8::Persistent<v8::Object> handle1, handle2;
12610 { 12691 {
12611 v8::HandleScope scope(isolate); 12692 v8::HandleScope scope(isolate);
12612 some_object.Reset(isolate, v8::Object::New()); 12693 some_object.Reset(isolate, v8::Object::New());
12613 handle1.Reset(isolate, v8::Object::New()); 12694 handle1.Reset(isolate, v8::Object::New());
12614 handle2.Reset(isolate, v8::Object::New()); 12695 handle2.Reset(isolate, v8::Object::New());
12615 } 12696 }
12616 // Note: order is implementation dependent alas: currently 12697 // Note: order is implementation dependent alas: currently
12617 // global handle nodes are processed by PostGarbageCollectionProcessing 12698 // global handle nodes are processed by PostGarbageCollectionProcessing
12618 // in reverse allocation order, so if second allocated handle is deleted, 12699 // in reverse allocation order, so if second allocated handle is deleted,
12619 // weak callback of the first handle would be able to 'reallocate' it. 12700 // weak callback of the first handle would be able to 'reallocate' it.
12620 handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback); 12701 handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback);
12621 handle2.Dispose(isolate); 12702 handle2.Dispose();
12622 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 12703 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12623 } 12704 }
12624 12705
12625 12706
12626 v8::Persistent<v8::Object> to_be_disposed; 12707 v8::Persistent<v8::Object> to_be_disposed;
12627 12708
12628 void DisposeAndForceGcCallback(v8::Isolate* isolate, 12709 void DisposeAndForceGcCallback(v8::Isolate* isolate,
12629 v8::Persistent<v8::Value>* handle, 12710 v8::Persistent<v8::Value>* handle,
12630 void*) { 12711 void*) {
12631 to_be_disposed.Dispose(isolate); 12712 to_be_disposed.Dispose();
12632 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 12713 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12633 handle->Dispose(isolate); 12714 handle->Dispose();
12634 } 12715 }
12635 12716
12636 12717
12637 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { 12718 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
12638 LocalContext context; 12719 LocalContext context;
12639 v8::Isolate* isolate = context->GetIsolate(); 12720 v8::Isolate* isolate = context->GetIsolate();
12640 12721
12641 v8::Persistent<v8::Object> handle1, handle2; 12722 v8::Persistent<v8::Object> handle1, handle2;
12642 { 12723 {
12643 v8::HandleScope scope(isolate); 12724 v8::HandleScope scope(isolate);
12644 handle1.Reset(isolate, v8::Object::New()); 12725 handle1.Reset(isolate, v8::Object::New());
12645 handle2.Reset(isolate, v8::Object::New()); 12726 handle2.Reset(isolate, v8::Object::New());
12646 } 12727 }
12647 handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback); 12728 handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback);
12648 to_be_disposed.Reset(isolate, handle2); 12729 to_be_disposed.Reset(isolate, handle2);
12649 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 12730 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12650 } 12731 }
12651 12732
12652 void DisposingCallback(v8::Isolate* isolate, 12733 void DisposingCallback(v8::Isolate* isolate,
12653 v8::Persistent<v8::Value>* handle, 12734 v8::Persistent<v8::Value>* handle,
12654 void*) { 12735 void*) {
12655 handle->Dispose(isolate); 12736 handle->Dispose();
12656 } 12737 }
12657 12738
12658 void HandleCreatingCallback(v8::Isolate* isolate, 12739 void HandleCreatingCallback(v8::Isolate* isolate,
12659 v8::Persistent<v8::Value>* handle, 12740 v8::Persistent<v8::Value>* handle,
12660 void*) { 12741 void*) {
12661 v8::HandleScope scope(isolate); 12742 v8::HandleScope scope(isolate);
12662 v8::Persistent<v8::Object>(isolate, v8::Object::New()); 12743 v8::Persistent<v8::Object>(isolate, v8::Object::New());
12663 handle->Dispose(isolate); 12744 handle->Dispose();
12664 } 12745 }
12665 12746
12666 12747
12667 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { 12748 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
12668 LocalContext context; 12749 LocalContext context;
12669 v8::Isolate* isolate = context->GetIsolate(); 12750 v8::Isolate* isolate = context->GetIsolate();
12670 12751
12671 v8::Persistent<v8::Object> handle1, handle2, handle3; 12752 v8::Persistent<v8::Object> handle1, handle2, handle3;
12672 { 12753 {
12673 v8::HandleScope scope(isolate); 12754 v8::HandleScope scope(isolate);
(...skipping 2316 matching lines...) Expand 10 before | Expand all | Expand 10 after
14990 "var x = obj.x;\n" 15071 "var x = obj.x;\n"
14991 "delete obj.y;\n" 15072 "delete obj.y;\n"
14992 "for (var i = 0; i < 5; i++) f(obj);"); 15073 "for (var i = 0; i < 5; i++) f(obj);");
14993 // Detach the global object to make 'this' refer directly to the 15074 // Detach the global object to make 'this' refer directly to the
14994 // global object (not the proxy), and make sure that the dictionary 15075 // global object (not the proxy), and make sure that the dictionary
14995 // load IC doesn't mess up loading directly from the global object. 15076 // load IC doesn't mess up loading directly from the global object.
14996 context->DetachGlobal(); 15077 context->DetachGlobal();
14997 CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value()); 15078 CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value());
14998 } 15079 }
14999 15080
15081 static void CheckElementValue(i::Isolate* isolate,
15082 int expected,
15083 i::Handle<i::Object> obj,
15084 int offset) {
15085 i::Object* element = obj->GetElement(isolate, offset)->ToObjectChecked();
15086 CHECK_EQ(expected, i::Smi::cast(element)->value());
15087 }
15088
15000 15089
15001 THREADED_TEST(PixelArray) { 15090 THREADED_TEST(PixelArray) {
15002 LocalContext context; 15091 LocalContext context;
15003 i::Factory* factory = i::Isolate::Current()->factory(); 15092 i::Isolate* isolate = i::Isolate::Current();
15093 i::Factory* factory = isolate->factory();
15004 v8::HandleScope scope(context->GetIsolate()); 15094 v8::HandleScope scope(context->GetIsolate());
15005 const int kElementCount = 260; 15095 const int kElementCount = 260;
15006 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); 15096 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
15007 i::Handle<i::ExternalPixelArray> pixels = 15097 i::Handle<i::ExternalPixelArray> pixels =
15008 i::Handle<i::ExternalPixelArray>::cast( 15098 i::Handle<i::ExternalPixelArray>::cast(
15009 factory->NewExternalArray(kElementCount, 15099 factory->NewExternalArray(kElementCount,
15010 v8::kExternalPixelArray, 15100 v8::kExternalPixelArray,
15011 pixel_data)); 15101 pixel_data));
15012 // Force GC to trigger verification. 15102 // Force GC to trigger verification.
15013 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 15103 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
15014 for (int i = 0; i < kElementCount; i++) { 15104 for (int i = 0; i < kElementCount; i++) {
15015 pixels->set(i, i % 256); 15105 pixels->set(i, i % 256);
15016 } 15106 }
15017 // Force GC to trigger verification. 15107 // Force GC to trigger verification.
15018 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 15108 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
15019 for (int i = 0; i < kElementCount; i++) { 15109 for (int i = 0; i < kElementCount; i++) {
15020 CHECK_EQ(i % 256, pixels->get_scalar(i)); 15110 CHECK_EQ(i % 256, pixels->get_scalar(i));
15021 CHECK_EQ(i % 256, pixel_data[i]); 15111 CHECK_EQ(i % 256, pixel_data[i]);
15022 } 15112 }
15023 15113
15024 v8::Handle<v8::Object> obj = v8::Object::New(); 15114 v8::Handle<v8::Object> obj = v8::Object::New();
15025 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); 15115 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
15026 // Set the elements to be the pixels. 15116 // Set the elements to be the pixels.
15027 // jsobj->set_elements(*pixels); 15117 // jsobj->set_elements(*pixels);
15028 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); 15118 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
15029 CHECK_EQ(1, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); 15119 CheckElementValue(isolate, 1, jsobj, 1);
15030 obj->Set(v8_str("field"), v8::Int32::New(1503)); 15120 obj->Set(v8_str("field"), v8::Int32::New(1503));
15031 context->Global()->Set(v8_str("pixels"), obj); 15121 context->Global()->Set(v8_str("pixels"), obj);
15032 v8::Handle<v8::Value> result = CompileRun("pixels.field"); 15122 v8::Handle<v8::Value> result = CompileRun("pixels.field");
15033 CHECK_EQ(1503, result->Int32Value()); 15123 CHECK_EQ(1503, result->Int32Value());
15034 result = CompileRun("pixels[1]"); 15124 result = CompileRun("pixels[1]");
15035 CHECK_EQ(1, result->Int32Value()); 15125 CHECK_EQ(1, result->Int32Value());
15036 15126
15037 result = CompileRun("var sum = 0;" 15127 result = CompileRun("var sum = 0;"
15038 "for (var i = 0; i < 8; i++) {" 15128 "for (var i = 0; i < 8; i++) {"
15039 " sum += pixels[i] = pixels[i] = -i;" 15129 " sum += pixels[i] = pixels[i] = -i;"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
15076 "sum;"); 15166 "sum;");
15077 CHECK_EQ(28, result->Int32Value()); 15167 CHECK_EQ(28, result->Int32Value());
15078 15168
15079 i::Handle<i::Smi> value(i::Smi::FromInt(2), 15169 i::Handle<i::Smi> value(i::Smi::FromInt(2),
15080 reinterpret_cast<i::Isolate*>(context->GetIsolate())); 15170 reinterpret_cast<i::Isolate*>(context->GetIsolate()));
15081 i::Handle<i::Object> no_failure; 15171 i::Handle<i::Object> no_failure;
15082 no_failure = 15172 no_failure =
15083 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); 15173 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
15084 ASSERT(!no_failure.is_null()); 15174 ASSERT(!no_failure.is_null());
15085 i::USE(no_failure); 15175 i::USE(no_failure);
15086 CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); 15176 CheckElementValue(isolate, 2, jsobj, 1);
15087 *value.location() = i::Smi::FromInt(256); 15177 *value.location() = i::Smi::FromInt(256);
15088 no_failure = 15178 no_failure =
15089 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); 15179 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
15090 ASSERT(!no_failure.is_null()); 15180 ASSERT(!no_failure.is_null());
15091 i::USE(no_failure); 15181 i::USE(no_failure);
15092 CHECK_EQ(255, 15182 CheckElementValue(isolate, 255, jsobj, 1);
15093 i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
15094 *value.location() = i::Smi::FromInt(-1); 15183 *value.location() = i::Smi::FromInt(-1);
15095 no_failure = 15184 no_failure =
15096 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode); 15185 i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
15097 ASSERT(!no_failure.is_null()); 15186 ASSERT(!no_failure.is_null());
15098 i::USE(no_failure); 15187 i::USE(no_failure);
15099 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); 15188 CheckElementValue(isolate, 0, jsobj, 1);
15100 15189
15101 result = CompileRun("for (var i = 0; i < 8; i++) {" 15190 result = CompileRun("for (var i = 0; i < 8; i++) {"
15102 " pixels[i] = (i * 65) - 109;" 15191 " pixels[i] = (i * 65) - 109;"
15103 "}" 15192 "}"
15104 "pixels[1] + pixels[6];"); 15193 "pixels[1] + pixels[6];");
15105 CHECK_EQ(255, result->Int32Value()); 15194 CHECK_EQ(255, result->Int32Value());
15106 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value()); 15195 CheckElementValue(isolate, 0, jsobj, 0);
15107 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); 15196 CheckElementValue(isolate, 0, jsobj, 1);
15108 CHECK_EQ(21, 15197 CheckElementValue(isolate, 21, jsobj, 2);
15109 i::Smi::cast(jsobj->GetElement(2)->ToObjectChecked())->value()); 15198 CheckElementValue(isolate, 86, jsobj, 3);
15110 CHECK_EQ(86, 15199 CheckElementValue(isolate, 151, jsobj, 4);
15111 i::Smi::cast(jsobj->GetElement(3)->ToObjectChecked())->value()); 15200 CheckElementValue(isolate, 216, jsobj, 5);
15112 CHECK_EQ(151, 15201 CheckElementValue(isolate, 255, jsobj, 6);
15113 i::Smi::cast(jsobj->GetElement(4)->ToObjectChecked())->value()); 15202 CheckElementValue(isolate, 255, jsobj, 7);
15114 CHECK_EQ(216,
15115 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
15116 CHECK_EQ(255,
15117 i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value());
15118 CHECK_EQ(255,
15119 i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value());
15120 result = CompileRun("var sum = 0;" 15203 result = CompileRun("var sum = 0;"
15121 "for (var i = 0; i < 8; i++) {" 15204 "for (var i = 0; i < 8; i++) {"
15122 " sum += pixels[i];" 15205 " sum += pixels[i];"
15123 "}" 15206 "}"
15124 "sum;"); 15207 "sum;");
15125 CHECK_EQ(984, result->Int32Value()); 15208 CHECK_EQ(984, result->Int32Value());
15126 15209
15127 result = CompileRun("for (var i = 0; i < 8; i++) {" 15210 result = CompileRun("for (var i = 0; i < 8; i++) {"
15128 " pixels[i] = (i * 1.1);" 15211 " pixels[i] = (i * 1.1);"
15129 "}" 15212 "}"
15130 "pixels[1] + pixels[6];"); 15213 "pixels[1] + pixels[6];");
15131 CHECK_EQ(8, result->Int32Value()); 15214 CHECK_EQ(8, result->Int32Value());
15132 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value()); 15215 CheckElementValue(isolate, 0, jsobj, 0);
15133 CHECK_EQ(1, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); 15216 CheckElementValue(isolate, 1, jsobj, 1);
15134 CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(2)->ToObjectChecked())->value()); 15217 CheckElementValue(isolate, 2, jsobj, 2);
15135 CHECK_EQ(3, i::Smi::cast(jsobj->GetElement(3)->ToObjectChecked())->value()); 15218 CheckElementValue(isolate, 3, jsobj, 3);
15136 CHECK_EQ(4, i::Smi::cast(jsobj->GetElement(4)->ToObjectChecked())->value()); 15219 CheckElementValue(isolate, 4, jsobj, 4);
15137 CHECK_EQ(6, i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value()); 15220 CheckElementValue(isolate, 6, jsobj, 5);
15138 CHECK_EQ(7, i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value()); 15221 CheckElementValue(isolate, 7, jsobj, 6);
15139 CHECK_EQ(8, i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value()); 15222 CheckElementValue(isolate, 8, jsobj, 7);
15140 15223
15141 result = CompileRun("for (var i = 0; i < 8; i++) {" 15224 result = CompileRun("for (var i = 0; i < 8; i++) {"
15142 " pixels[7] = undefined;" 15225 " pixels[7] = undefined;"
15143 "}" 15226 "}"
15144 "pixels[7];"); 15227 "pixels[7];");
15145 CHECK_EQ(0, result->Int32Value()); 15228 CHECK_EQ(0, result->Int32Value());
15146 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value()); 15229 CheckElementValue(isolate, 0, jsobj, 7);
15147 15230
15148 result = CompileRun("for (var i = 0; i < 8; i++) {" 15231 result = CompileRun("for (var i = 0; i < 8; i++) {"
15149 " pixels[6] = '2.3';" 15232 " pixels[6] = '2.3';"
15150 "}" 15233 "}"
15151 "pixels[6];"); 15234 "pixels[6];");
15152 CHECK_EQ(2, result->Int32Value()); 15235 CHECK_EQ(2, result->Int32Value());
15153 CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value()); 15236 CheckElementValue(isolate, 2, jsobj, 6);
15154 15237
15155 result = CompileRun("for (var i = 0; i < 8; i++) {" 15238 result = CompileRun("for (var i = 0; i < 8; i++) {"
15156 " pixels[5] = NaN;" 15239 " pixels[5] = NaN;"
15157 "}" 15240 "}"
15158 "pixels[5];"); 15241 "pixels[5];");
15159 CHECK_EQ(0, result->Int32Value()); 15242 CHECK_EQ(0, result->Int32Value());
15160 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value()); 15243 CheckElementValue(isolate, 0, jsobj, 5);
15161 15244
15162 result = CompileRun("for (var i = 0; i < 8; i++) {" 15245 result = CompileRun("for (var i = 0; i < 8; i++) {"
15163 " pixels[8] = Infinity;" 15246 " pixels[8] = Infinity;"
15164 "}" 15247 "}"
15165 "pixels[8];"); 15248 "pixels[8];");
15166 CHECK_EQ(255, result->Int32Value()); 15249 CHECK_EQ(255, result->Int32Value());
15167 CHECK_EQ(255, 15250 CheckElementValue(isolate, 255, jsobj, 8);
15168 i::Smi::cast(jsobj->GetElement(8)->ToObjectChecked())->value());
15169 15251
15170 result = CompileRun("for (var i = 0; i < 8; i++) {" 15252 result = CompileRun("for (var i = 0; i < 8; i++) {"
15171 " pixels[9] = -Infinity;" 15253 " pixels[9] = -Infinity;"
15172 "}" 15254 "}"
15173 "pixels[9];"); 15255 "pixels[9];");
15174 CHECK_EQ(0, result->Int32Value()); 15256 CHECK_EQ(0, result->Int32Value());
15175 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(9)->ToObjectChecked())->value()); 15257 CheckElementValue(isolate, 0, jsobj, 9);
15176 15258
15177 result = CompileRun("pixels[3] = 33;" 15259 result = CompileRun("pixels[3] = 33;"
15178 "delete pixels[3];" 15260 "delete pixels[3];"
15179 "pixels[3];"); 15261 "pixels[3];");
15180 CHECK_EQ(33, result->Int32Value()); 15262 CHECK_EQ(33, result->Int32Value());
15181 15263
15182 result = CompileRun("pixels[0] = 10; pixels[1] = 11;" 15264 result = CompileRun("pixels[0] = 10; pixels[1] = 11;"
15183 "pixels[2] = 12; pixels[3] = 13;" 15265 "pixels[2] = 12; pixels[3] = 13;"
15184 "pixels.__defineGetter__('2'," 15266 "pixels.__defineGetter__('2',"
15185 "function() { return 120; });" 15267 "function() { return 120; });"
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
15482 15564
15483 15565
15484 template <class ExternalArrayClass, class ElementType> 15566 template <class ExternalArrayClass, class ElementType>
15485 static void ObjectWithExternalArrayTestHelper( 15567 static void ObjectWithExternalArrayTestHelper(
15486 Handle<Context> context, 15568 Handle<Context> context,
15487 v8::Handle<Object> obj, 15569 v8::Handle<Object> obj,
15488 int element_count, 15570 int element_count,
15489 v8::ExternalArrayType array_type, 15571 v8::ExternalArrayType array_type,
15490 int64_t low, int64_t high) { 15572 int64_t low, int64_t high) {
15491 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); 15573 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
15574 i::Isolate* isolate = jsobj->GetIsolate();
15492 obj->Set(v8_str("field"), v8::Int32::New(1503)); 15575 obj->Set(v8_str("field"), v8::Int32::New(1503));
15493 context->Global()->Set(v8_str("ext_array"), obj); 15576 context->Global()->Set(v8_str("ext_array"), obj);
15494 v8::Handle<v8::Value> result = CompileRun("ext_array.field"); 15577 v8::Handle<v8::Value> result = CompileRun("ext_array.field");
15495 CHECK_EQ(1503, result->Int32Value()); 15578 CHECK_EQ(1503, result->Int32Value());
15496 result = CompileRun("ext_array[1]"); 15579 result = CompileRun("ext_array[1]");
15497 CHECK_EQ(1, result->Int32Value()); 15580 CHECK_EQ(1, result->Int32Value());
15498 15581
15499 // Check pass through of assigned smis 15582 // Check pass through of assigned smis
15500 result = CompileRun("var sum = 0;" 15583 result = CompileRun("var sum = 0;"
15501 "for (var i = 0; i < 8; i++) {" 15584 "for (var i = 0; i < 8; i++) {"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
15623 CHECK_EQ(false, result->BooleanValue()); 15706 CHECK_EQ(false, result->BooleanValue());
15624 15707
15625 // Check other boundary conditions, values and operations. 15708 // Check other boundary conditions, values and operations.
15626 result = CompileRun("for (var i = 0; i < 8; i++) {" 15709 result = CompileRun("for (var i = 0; i < 8; i++) {"
15627 " ext_array[7] = undefined;" 15710 " ext_array[7] = undefined;"
15628 "}" 15711 "}"
15629 "ext_array[7];"); 15712 "ext_array[7];");
15630 CHECK_EQ(0, result->Int32Value()); 15713 CHECK_EQ(0, result->Int32Value());
15631 if (array_type == v8::kExternalDoubleArray || 15714 if (array_type == v8::kExternalDoubleArray ||
15632 array_type == v8::kExternalFloatArray) { 15715 array_type == v8::kExternalFloatArray) {
15633 CHECK_EQ( 15716 CHECK_EQ(static_cast<int>(i::OS::nan_value()),
15634 static_cast<int>(i::OS::nan_value()), 15717 static_cast<int>(
15635 static_cast<int>(jsobj->GetElement(7)->ToObjectChecked()->Number())); 15718 jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number()));
15636 } else { 15719 } else {
15637 CHECK_EQ(0, static_cast<int>( 15720 CheckElementValue(isolate, 0, jsobj, 7);
15638 jsobj->GetElement(7)->ToObjectChecked()->Number()));
15639 } 15721 }
15640 15722
15641 result = CompileRun("for (var i = 0; i < 8; i++) {" 15723 result = CompileRun("for (var i = 0; i < 8; i++) {"
15642 " ext_array[6] = '2.3';" 15724 " ext_array[6] = '2.3';"
15643 "}" 15725 "}"
15644 "ext_array[6];"); 15726 "ext_array[6];");
15645 CHECK_EQ(2, result->Int32Value()); 15727 CHECK_EQ(2, result->Int32Value());
15646 CHECK_EQ( 15728 CHECK_EQ(2,
15647 2, static_cast<int>(jsobj->GetElement(6)->ToObjectChecked()->Number())); 15729 static_cast<int>(
15730 jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number()));
15648 15731
15649 if (array_type != v8::kExternalFloatArray && 15732 if (array_type != v8::kExternalFloatArray &&
15650 array_type != v8::kExternalDoubleArray) { 15733 array_type != v8::kExternalDoubleArray) {
15651 // Though the specification doesn't state it, be explicit about 15734 // Though the specification doesn't state it, be explicit about
15652 // converting NaNs and +/-Infinity to zero. 15735 // converting NaNs and +/-Infinity to zero.
15653 result = CompileRun("for (var i = 0; i < 8; i++) {" 15736 result = CompileRun("for (var i = 0; i < 8; i++) {"
15654 " ext_array[i] = 5;" 15737 " ext_array[i] = 5;"
15655 "}" 15738 "}"
15656 "for (var i = 0; i < 8; i++) {" 15739 "for (var i = 0; i < 8; i++) {"
15657 " ext_array[i] = NaN;" 15740 " ext_array[i] = NaN;"
15658 "}" 15741 "}"
15659 "ext_array[5];"); 15742 "ext_array[5];");
15660 CHECK_EQ(0, result->Int32Value()); 15743 CHECK_EQ(0, result->Int32Value());
15661 CHECK_EQ(0, 15744 CheckElementValue(isolate, 0, jsobj, 5);
15662 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
15663 15745
15664 result = CompileRun("for (var i = 0; i < 8; i++) {" 15746 result = CompileRun("for (var i = 0; i < 8; i++) {"
15665 " ext_array[i] = 5;" 15747 " ext_array[i] = 5;"
15666 "}" 15748 "}"
15667 "for (var i = 0; i < 8; i++) {" 15749 "for (var i = 0; i < 8; i++) {"
15668 " ext_array[i] = Infinity;" 15750 " ext_array[i] = Infinity;"
15669 "}" 15751 "}"
15670 "ext_array[5];"); 15752 "ext_array[5];");
15671 int expected_value = 15753 int expected_value =
15672 (array_type == v8::kExternalPixelArray) ? 255 : 0; 15754 (array_type == v8::kExternalPixelArray) ? 255 : 0;
15673 CHECK_EQ(expected_value, result->Int32Value()); 15755 CHECK_EQ(expected_value, result->Int32Value());
15674 CHECK_EQ(expected_value, 15756 CheckElementValue(isolate, expected_value, jsobj, 5);
15675 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
15676 15757
15677 result = CompileRun("for (var i = 0; i < 8; i++) {" 15758 result = CompileRun("for (var i = 0; i < 8; i++) {"
15678 " ext_array[i] = 5;" 15759 " ext_array[i] = 5;"
15679 "}" 15760 "}"
15680 "for (var i = 0; i < 8; i++) {" 15761 "for (var i = 0; i < 8; i++) {"
15681 " ext_array[i] = -Infinity;" 15762 " ext_array[i] = -Infinity;"
15682 "}" 15763 "}"
15683 "ext_array[5];"); 15764 "ext_array[5];");
15684 CHECK_EQ(0, result->Int32Value()); 15765 CHECK_EQ(0, result->Int32Value());
15685 CHECK_EQ(0, 15766 CheckElementValue(isolate, 0, jsobj, 5);
15686 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
15687 15767
15688 // Check truncation behavior of integral arrays. 15768 // Check truncation behavior of integral arrays.
15689 const char* unsigned_data = 15769 const char* unsigned_data =
15690 "var source_data = [0.6, 10.6];" 15770 "var source_data = [0.6, 10.6];"
15691 "var expected_results = [0, 10];"; 15771 "var expected_results = [0, 10];";
15692 const char* signed_data = 15772 const char* signed_data =
15693 "var source_data = [0.6, 10.6, -0.6, -10.6];" 15773 "var source_data = [0.6, 10.6, -0.6, -10.6];"
15694 "var expected_results = [0, 10, 0, -10];"; 15774 "var expected_results = [0, 10, 0, -10];";
15695 const char* pixel_data = 15775 const char* pixel_data =
15696 "var source_data = [0.6, 10.6];" 15776 "var source_data = [0.6, 10.6];"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
15782 result = CompileRun("ext_array[1] = 23;"); 15862 result = CompileRun("ext_array[1] = 23;");
15783 CHECK_EQ(23, result->Int32Value()); 15863 CHECK_EQ(23, result->Int32Value());
15784 } 15864 }
15785 15865
15786 15866
15787 template <class ExternalArrayClass, class ElementType> 15867 template <class ExternalArrayClass, class ElementType>
15788 static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, 15868 static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
15789 int64_t low, 15869 int64_t low,
15790 int64_t high) { 15870 int64_t high) {
15791 LocalContext context; 15871 LocalContext context;
15792 i::Factory* factory = i::Isolate::Current()->factory(); 15872 i::Isolate* isolate = i::Isolate::Current();
15873 i::Factory* factory = isolate->factory();
15793 v8::HandleScope scope(context->GetIsolate()); 15874 v8::HandleScope scope(context->GetIsolate());
15794 const int kElementCount = 40; 15875 const int kElementCount = 40;
15795 int element_size = ExternalArrayElementSize(array_type); 15876 int element_size = ExternalArrayElementSize(array_type);
15796 ElementType* array_data = 15877 ElementType* array_data =
15797 static_cast<ElementType*>(malloc(kElementCount * element_size)); 15878 static_cast<ElementType*>(malloc(kElementCount * element_size));
15798 i::Handle<ExternalArrayClass> array = 15879 i::Handle<ExternalArrayClass> array =
15799 i::Handle<ExternalArrayClass>::cast( 15880 i::Handle<ExternalArrayClass>::cast(
15800 factory->NewExternalArray(kElementCount, array_type, array_data)); 15881 factory->NewExternalArray(kElementCount, array_type, array_data));
15801 // Force GC to trigger verification. 15882 // Force GC to trigger verification.
15802 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 15883 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
15803 for (int i = 0; i < kElementCount; i++) { 15884 for (int i = 0; i < kElementCount; i++) {
15804 array->set(i, static_cast<ElementType>(i)); 15885 array->set(i, static_cast<ElementType>(i));
15805 } 15886 }
15806 // Force GC to trigger verification. 15887 // Force GC to trigger verification.
15807 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 15888 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
15808 for (int i = 0; i < kElementCount; i++) { 15889 for (int i = 0; i < kElementCount; i++) {
15809 CHECK_EQ(static_cast<int64_t>(i), 15890 CHECK_EQ(static_cast<int64_t>(i),
15810 static_cast<int64_t>(array->get_scalar(i))); 15891 static_cast<int64_t>(array->get_scalar(i)));
15811 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); 15892 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i]));
15812 } 15893 }
15813 15894
15814 v8::Handle<v8::Object> obj = v8::Object::New(); 15895 v8::Handle<v8::Object> obj = v8::Object::New();
15815 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); 15896 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
15816 // Set the elements to be the external array. 15897 // Set the elements to be the external array.
15817 obj->SetIndexedPropertiesToExternalArrayData(array_data, 15898 obj->SetIndexedPropertiesToExternalArrayData(array_data,
15818 array_type, 15899 array_type,
15819 kElementCount); 15900 kElementCount);
15820 CHECK_EQ( 15901 CHECK_EQ(1,
15821 1, static_cast<int>(jsobj->GetElement(1)->ToObjectChecked()->Number())); 15902 static_cast<int>(
15903 jsobj->GetElement(isolate, 1)->ToObjectChecked()->Number()));
15822 15904
15823 ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>( 15905 ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>(
15824 context.local(), obj, kElementCount, array_type, low, high); 15906 context.local(), obj, kElementCount, array_type, low, high);
15825 15907
15826 v8::Handle<v8::Value> result; 15908 v8::Handle<v8::Value> result;
15827 15909
15828 // Test more complex manipulations which cause eax to contain values 15910 // Test more complex manipulations which cause eax to contain values
15829 // that won't be completely overwritten by loads from the arrays. 15911 // that won't be completely overwritten by loads from the arrays.
15830 // This catches bugs in the instructions used for the KeyedLoadIC 15912 // This catches bugs in the instructions used for the KeyedLoadIC
15831 // for byte and word types. 15913 // for byte and word types.
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after
18583 int counter_; 18665 int counter_;
18584 v8::Persistent<v8::Object>* object_; 18666 v8::Persistent<v8::Object>* object_;
18585 }; 18667 };
18586 18668
18587 18669
18588 TEST(PersistentHandleVisitor) { 18670 TEST(PersistentHandleVisitor) {
18589 LocalContext context; 18671 LocalContext context;
18590 v8::Isolate* isolate = context->GetIsolate(); 18672 v8::Isolate* isolate = context->GetIsolate();
18591 v8::HandleScope scope(isolate); 18673 v8::HandleScope scope(isolate);
18592 v8::Persistent<v8::Object> object(isolate, v8::Object::New()); 18674 v8::Persistent<v8::Object> object(isolate, v8::Object::New());
18593 CHECK_EQ(0, object.WrapperClassId(isolate)); 18675 CHECK_EQ(0, object.WrapperClassId());
18594 object.SetWrapperClassId(isolate, 42); 18676 object.SetWrapperClassId(42);
18595 CHECK_EQ(42, object.WrapperClassId(isolate)); 18677 CHECK_EQ(42, object.WrapperClassId());
18596 18678
18597 Visitor42 visitor(&object); 18679 Visitor42 visitor(&object);
18598 v8::V8::VisitHandlesWithClassIds(&visitor); 18680 v8::V8::VisitHandlesWithClassIds(&visitor);
18599 CHECK_EQ(1, visitor.counter_); 18681 CHECK_EQ(1, visitor.counter_);
18600 18682
18601 object.Dispose(isolate); 18683 object.Dispose();
18602 } 18684 }
18603 18685
18604 18686
18605 TEST(WrapperClassId) { 18687 TEST(WrapperClassId) {
18606 LocalContext context; 18688 LocalContext context;
18607 v8::Isolate* isolate = context->GetIsolate(); 18689 v8::Isolate* isolate = context->GetIsolate();
18608 v8::HandleScope scope(isolate); 18690 v8::HandleScope scope(isolate);
18609 v8::Persistent<v8::Object> object(isolate, v8::Object::New()); 18691 v8::Persistent<v8::Object> object(isolate, v8::Object::New());
18610 CHECK_EQ(0, object.WrapperClassId(isolate)); 18692 CHECK_EQ(0, object.WrapperClassId());
18611 object.SetWrapperClassId(isolate, 65535); 18693 object.SetWrapperClassId(65535);
18612 CHECK_EQ(65535, object.WrapperClassId(isolate)); 18694 CHECK_EQ(65535, object.WrapperClassId());
18613 object.Dispose(isolate); 18695 object.Dispose();
18614 } 18696 }
18615 18697
18616 18698
18617 TEST(PersistentHandleInNewSpaceVisitor) { 18699 TEST(PersistentHandleInNewSpaceVisitor) {
18618 LocalContext context; 18700 LocalContext context;
18619 v8::Isolate* isolate = context->GetIsolate(); 18701 v8::Isolate* isolate = context->GetIsolate();
18620 v8::HandleScope scope(isolate); 18702 v8::HandleScope scope(isolate);
18621 v8::Persistent<v8::Object> object1(isolate, v8::Object::New()); 18703 v8::Persistent<v8::Object> object1(isolate, v8::Object::New());
18622 CHECK_EQ(0, object1.WrapperClassId(isolate)); 18704 CHECK_EQ(0, object1.WrapperClassId());
18623 object1.SetWrapperClassId(isolate, 42); 18705 object1.SetWrapperClassId(42);
18624 CHECK_EQ(42, object1.WrapperClassId(isolate)); 18706 CHECK_EQ(42, object1.WrapperClassId());
18625 18707
18626 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 18708 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
18627 18709
18628 v8::Persistent<v8::Object> object2(isolate, v8::Object::New()); 18710 v8::Persistent<v8::Object> object2(isolate, v8::Object::New());
18629 CHECK_EQ(0, object2.WrapperClassId(isolate)); 18711 CHECK_EQ(0, object2.WrapperClassId());
18630 object2.SetWrapperClassId(isolate, 42); 18712 object2.SetWrapperClassId(42);
18631 CHECK_EQ(42, object2.WrapperClassId(isolate)); 18713 CHECK_EQ(42, object2.WrapperClassId());
18632 18714
18633 Visitor42 visitor(&object2); 18715 Visitor42 visitor(&object2);
18634 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor); 18716 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
18635 CHECK_EQ(1, visitor.counter_); 18717 CHECK_EQ(1, visitor.counter_);
18636 18718
18637 object1.Dispose(isolate); 18719 object1.Dispose();
18638 object2.Dispose(isolate); 18720 object2.Dispose();
18639 } 18721 }
18640 18722
18641 18723
18642 TEST(RegExp) { 18724 TEST(RegExp) {
18643 LocalContext context; 18725 LocalContext context;
18644 v8::HandleScope scope(context->GetIsolate()); 18726 v8::HandleScope scope(context->GetIsolate());
18645 18727
18646 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone); 18728 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone);
18647 CHECK(re->IsRegExp()); 18729 CHECK(re->IsRegExp());
18648 CHECK(re->GetSource()->Equals(v8_str("foo"))); 18730 CHECK(re->GetSource()->Equals(v8_str("foo")));
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
20313 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); 20395 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
20314 context->Global()->Set(v8_str("Bug"), templ->GetFunction()); 20396 context->Global()->Set(v8_str("Bug"), templ->GetFunction());
20315 CompileRun("\"use strict\"; var o = new Bug;" 20397 CompileRun("\"use strict\"; var o = new Bug;"
20316 "function f(o) { o.x = 10; };" 20398 "function f(o) { o.x = 10; };"
20317 "f(o); f(o); f(o);" 20399 "f(o); f(o); f(o);"
20318 "%OptimizeFunctionOnNextCall(f);" 20400 "%OptimizeFunctionOnNextCall(f);"
20319 "f(o);"); 20401 "f(o);");
20320 ExpectBoolean("%GetOptimizationStatus(f) != 2", true); 20402 ExpectBoolean("%GetOptimizationStatus(f) != 2", true);
20321 } 20403 }
20322 20404
20405
20406 THREADED_TEST(CrankshaftInterceptorSetter) {
20407 i::FLAG_allow_natives_syntax = true;
20408 v8::HandleScope scope(v8::Isolate::GetCurrent());
20409 Handle<FunctionTemplate> templ = FunctionTemplate::New();
20410 AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
20411 LocalContext env;
20412 env->Global()->Set(v8_str("Obj"), templ->GetFunction());
20413 CompileRun("var obj = new Obj;"
20414 // Initialize fields to avoid transitions later.
20415 "obj.age = 0;"
20416 "obj.accessor_age = 42;"
20417 "function setter(i) { this.accessor_age = i; };"
20418 "function getter() { return this.accessor_age; };"
20419 "function setAge(i) { obj.age = i; };"
20420 "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
20421 "setAge(1);"
20422 "setAge(2);"
20423 "setAge(3);"
20424 "%OptimizeFunctionOnNextCall(setAge);"
20425 "setAge(4);");
20426 // All stores went through the interceptor.
20427 ExpectInt32("obj.interceptor_age", 4);
20428 ExpectInt32("obj.accessor_age", 42);
20429 }
20430
20431
20432 THREADED_TEST(CrankshaftInterceptorGetter) {
20433 i::FLAG_allow_natives_syntax = true;
20434 v8::HandleScope scope(v8::Isolate::GetCurrent());
20435 Handle<FunctionTemplate> templ = FunctionTemplate::New();
20436 AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
20437 LocalContext env;
20438 env->Global()->Set(v8_str("Obj"), templ->GetFunction());
20439 CompileRun("var obj = new Obj;"
20440 // Initialize fields to avoid transitions later.
20441 "obj.age = 1;"
20442 "obj.accessor_age = 42;"
20443 "function getter() { return this.accessor_age; };"
20444 "function getAge() { return obj.interceptor_age; };"
20445 "Object.defineProperty(obj, 'interceptor_age', { get:getter });"
20446 "getAge();"
20447 "getAge();"
20448 "getAge();"
20449 "%OptimizeFunctionOnNextCall(getAge);");
20450 // Access through interceptor.
20451 ExpectInt32("getAge()", 1);
20452 }
20453
20454
20455 THREADED_TEST(CrankshaftInterceptorFieldRead) {
20456 i::FLAG_allow_natives_syntax = true;
20457 v8::HandleScope scope(v8::Isolate::GetCurrent());
20458 Handle<FunctionTemplate> templ = FunctionTemplate::New();
20459 AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
20460 LocalContext env;
20461 env->Global()->Set(v8_str("Obj"), templ->GetFunction());
20462 CompileRun("var obj = new Obj;"
20463 "obj.__proto__.interceptor_age = 42;"
20464 "obj.age = 100;"
20465 "function getAge() { return obj.interceptor_age; };");
20466 ExpectInt32("getAge();", 100);
20467 ExpectInt32("getAge();", 100);
20468 ExpectInt32("getAge();", 100);
20469 CompileRun("%OptimizeFunctionOnNextCall(getAge);");
20470 // Access through interceptor.
20471 ExpectInt32("getAge();", 100);
20472 }
20473
20474
20475 THREADED_TEST(CrankshaftInterceptorFieldWrite) {
20476 i::FLAG_allow_natives_syntax = true;
20477 v8::HandleScope scope(v8::Isolate::GetCurrent());
20478 Handle<FunctionTemplate> templ = FunctionTemplate::New();
20479 AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
20480 LocalContext env;
20481 env->Global()->Set(v8_str("Obj"), templ->GetFunction());
20482 CompileRun("var obj = new Obj;"
20483 "obj.age = 100000;"
20484 "function setAge(i) { obj.age = i };"
20485 "setAge(100);"
20486 "setAge(101);"
20487 "setAge(102);"
20488 "%OptimizeFunctionOnNextCall(setAge);"
20489 "setAge(103);");
20490 ExpectInt32("obj.age", 100000);
20491 ExpectInt32("obj.interceptor_age", 103);
20492 }
20493
20494
20323 #endif // V8_OS_POSIX 20495 #endif // V8_OS_POSIX
20496
20497
20498 static Local<Value> function_new_expected_env;
20499 static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
20500 CHECK_EQ(function_new_expected_env, info.Data());
20501 info.GetReturnValue().Set(17);
20502 }
20503
20504
20505 THREADED_TEST(FunctionNew) {
20506 LocalContext env;
20507 v8::Isolate* isolate = env->GetIsolate();
20508 v8::HandleScope scope(isolate);
20509 Local<Object> data = v8::Object::New();
20510 function_new_expected_env = data;
20511 Local<Function> func = Function::New(isolate, FunctionNewCallback, data);
20512 env->Global()->Set(v8_str("func"), func);
20513 Local<Value> result = CompileRun("func();");
20514 CHECK_EQ(v8::Integer::New(17, isolate), result);
20515 // Verify function not cached
20516 int serial_number =
20517 i::Smi::cast(v8::Utils::OpenHandle(*func)
20518 ->shared()->get_api_func_data()->serial_number())->value();
20519 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
20520 i::Object* elm = i_isolate->native_context()->function_cache()
20521 ->GetElementNoExceptionThrown(i_isolate, serial_number);
20522 CHECK(elm->IsNull());
20523 }
20524
OLDNEW
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-circular-queue.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698