| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |