| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 15 matching lines...) Expand all Loading... |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 | 31 |
| 32 #include "arguments.h" | 32 #include "arguments.h" |
| 33 #include "bootstrapper.h" | 33 #include "bootstrapper.h" |
| 34 #include "compiler.h" | 34 #include "compiler.h" |
| 35 #include "debug.h" | 35 #include "debug.h" |
| 36 #include "deoptimizer.h" |
| 36 #include "execution.h" | 37 #include "execution.h" |
| 37 #include "global-handles.h" | 38 #include "global-handles.h" |
| 38 #include "heap-profiler.h" | 39 #include "heap-profiler.h" |
| 39 #include "messages.h" | 40 #include "messages.h" |
| 40 #include "parser.h" | 41 #include "parser.h" |
| 41 #include "platform.h" | 42 #include "platform.h" |
| 42 #include "profile-generator-inl.h" | 43 #include "profile-generator-inl.h" |
| 44 #include "runtime-profiler.h" |
| 43 #include "serialize.h" | 45 #include "serialize.h" |
| 44 #include "snapshot.h" | 46 #include "snapshot.h" |
| 45 #include "v8threads.h" | 47 #include "v8threads.h" |
| 46 #include "version.h" | 48 #include "version.h" |
| 49 #include "vm-state-inl.h" |
| 47 | 50 |
| 48 #include "../include/v8-profiler.h" | 51 #include "../include/v8-profiler.h" |
| 52 #include "../include/v8-testing.h" |
| 49 | 53 |
| 50 #define LOG_API(expr) LOG(ApiEntryCall(expr)) | 54 #define LOG_API(expr) LOG(ApiEntryCall(expr)) |
| 51 | 55 |
| 52 // TODO(isolates): avoid repeated TLS reads in function prologues. | 56 // TODO(isolates): avoid repeated TLS reads in function prologues. |
| 53 #ifdef ENABLE_VMSTATE_TRACKING | 57 #ifdef ENABLE_VMSTATE_TRACKING |
| 54 #define ENTER_V8 i::VMState __state__(i::Isolate::Current(), i::OTHER) | 58 #define ENTER_V8 \ |
| 55 #define LEAVE_V8 i::VMState __state__(i::Isolate::Current(), i::EXTERNAL) | 59 ASSERT(i::Isolate::Current()->IsInitialized()); \ |
| 60 i::VMState __state__(i::Isolate::Current(), i::OTHER) |
| 61 #define LEAVE_V8 \ |
| 62 i::VMState __state__(i::Isolate::Current(), i::EXTERNAL) |
| 56 #else | 63 #else |
| 57 #define ENTER_V8 ((void) 0) | 64 #define ENTER_V8 ((void) 0) |
| 58 #define LEAVE_V8 ((void) 0) | 65 #define LEAVE_V8 ((void) 0) |
| 59 #endif | 66 #endif |
| 60 | 67 |
| 61 namespace v8 { | 68 namespace v8 { |
| 62 | 69 |
| 63 #define ON_BAILOUT(location, code) \ | 70 #define ON_BAILOUT(location, code) \ |
| 64 if (IsDeadCheck(location) || v8::V8::IsExecutionTerminating()) { \ | 71 if (IsDeadCheck(location) || v8::V8::IsExecutionTerminating()) { \ |
| 65 code; \ | 72 code; \ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 IsLockedByCurrentThread(), \ | 107 IsLockedByCurrentThread(), \ |
| 101 msg, \ | 108 msg, \ |
| 102 "Entering the V8 API without proper locking in place"); \ | 109 "Entering the V8 API without proper locking in place"); \ |
| 103 } \ | 110 } \ |
| 104 } while (false) | 111 } while (false) |
| 105 | 112 |
| 106 | 113 |
| 107 // --- E x c e p t i o n B e h a v i o r --- | 114 // --- E x c e p t i o n B e h a v i o r --- |
| 108 | 115 |
| 109 | 116 |
| 110 | |
| 111 static void DefaultFatalErrorHandler(const char* location, | 117 static void DefaultFatalErrorHandler(const char* location, |
| 112 const char* message) { | 118 const char* message) { |
| 113 ENTER_V8; | 119 ENTER_V8; |
| 114 API_Fatal(location, message); | 120 API_Fatal(location, message); |
| 115 } | 121 } |
| 116 | 122 |
| 117 | 123 |
| 118 static FatalErrorCallback GetFatalErrorHandler() { | 124 static FatalErrorCallback GetFatalErrorHandler() { |
| 119 i::Isolate* isolate = i::Isolate::Current(); | 125 i::Isolate* isolate = i::Isolate::Current(); |
| 120 if (isolate->exception_behavior() == NULL) { | 126 if (isolate->exception_behavior() == NULL) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 * entry to all methods that touch anything in the heap, except destructors | 247 * entry to all methods that touch anything in the heap, except destructors |
| 242 * which you sometimes can't avoid calling after the vm has crashed. Functions | 248 * which you sometimes can't avoid calling after the vm has crashed. Functions |
| 243 * that call EnsureInitialized or ON_BAILOUT don't have to also call | 249 * that call EnsureInitialized or ON_BAILOUT don't have to also call |
| 244 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you | 250 * IsDeadCheck. ON_BAILOUT has the advantage over EnsureInitialized that you |
| 245 * can arrange to return if the VM is dead. This is needed to ensure that no VM | 251 * can arrange to return if the VM is dead. This is needed to ensure that no VM |
| 246 * heap allocations are attempted on a dead VM. EnsureInitialized has the | 252 * heap allocations are attempted on a dead VM. EnsureInitialized has the |
| 247 * advantage over ON_BAILOUT that it actually initializes the VM if this has not | 253 * advantage over ON_BAILOUT that it actually initializes the VM if this has not |
| 248 * yet been done. | 254 * yet been done. |
| 249 */ | 255 */ |
| 250 static inline bool IsDeadCheck(const char* location) { | 256 static inline bool IsDeadCheck(const char* location) { |
| 251 return !i::V8::IsRunning() | 257 return !i::Isolate::Current()->IsInitialized() |
| 252 && i::V8::IsDead() ? ReportV8Dead(location) : false; | 258 && i::V8::IsDead() ? ReportV8Dead(location) : false; |
| 253 } | 259 } |
| 254 | 260 |
| 255 | 261 |
| 256 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) { | 262 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) { |
| 257 return obj.IsEmpty() ? ReportEmptyHandle(location) : false; | 263 return obj.IsEmpty() ? ReportEmptyHandle(location) : false; |
| 258 } | 264 } |
| 259 | 265 |
| 260 | 266 |
| 261 static inline bool EmptyCheck(const char* location, const v8::Data* obj) { | 267 static inline bool EmptyCheck(const char* location, const v8::Data* obj) { |
| 262 return (obj == 0) ? ReportEmptyHandle(location) : false; | 268 return (obj == 0) ? ReportEmptyHandle(location) : false; |
| 263 } | 269 } |
| 264 | 270 |
| 265 // --- S t a t i c s --- | 271 // --- S t a t i c s --- |
| 266 | 272 |
| 267 | 273 |
| 268 static bool InitializeHelper() { | 274 static bool InitializeHelper() { |
| 269 if (i::Snapshot::Initialize()) return true; | 275 if (i::Snapshot::Initialize()) return true; |
| 270 return i::V8::Initialize(NULL); | 276 return i::V8::Initialize(NULL); |
| 271 } | 277 } |
| 272 | 278 |
| 273 | 279 |
| 274 static inline bool EnsureInitializedForIsolate(i::Isolate* isolate, | 280 static inline bool EnsureInitializedForIsolate(i::Isolate* isolate, |
| 275 const char* location) { | 281 const char* location) { |
| 282 if (IsDeadCheck(location)) return false; |
| 276 if (isolate != NULL) { | 283 if (isolate != NULL) { |
| 277 if (isolate->IsDefaultIsolate()) { | 284 if (isolate->IsInitialized()) return true; |
| 278 if (i::V8::IsRunning()) { | |
| 279 return true; | |
| 280 } | |
| 281 if (IsDeadCheck(location)) { | |
| 282 return false; | |
| 283 } | |
| 284 } else { | |
| 285 if (isolate->IsInitialized()) { | |
| 286 return true; | |
| 287 } | |
| 288 } | |
| 289 } | 285 } |
| 290 return ApiCheck(InitializeHelper(), location, "Error initializing V8"); | 286 return ApiCheck(InitializeHelper(), location, "Error initializing V8"); |
| 291 } | 287 } |
| 292 | 288 |
| 293 static inline bool EnsureInitialized(const char* location) { | 289 static inline bool EnsureInitialized(const char* location) { |
| 294 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 290 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
| 295 return EnsureInitializedForIsolate(isolate, location); | 291 return EnsureInitializedForIsolate(isolate, location); |
| 296 } | 292 } |
| 297 | 293 |
| 298 #ifdef DEBUG | 294 #ifdef DEBUG |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 | 449 |
| 454 | 450 |
| 455 void V8::ClearWeak(i::Object** obj) { | 451 void V8::ClearWeak(i::Object** obj) { |
| 456 LOG_API("ClearWeak"); | 452 LOG_API("ClearWeak"); |
| 457 i::Isolate::Current()->global_handles()->ClearWeakness(obj); | 453 i::Isolate::Current()->global_handles()->ClearWeakness(obj); |
| 458 } | 454 } |
| 459 | 455 |
| 460 | 456 |
| 461 bool V8::IsGlobalNearDeath(i::Object** obj) { | 457 bool V8::IsGlobalNearDeath(i::Object** obj) { |
| 462 LOG_API("IsGlobalNearDeath"); | 458 LOG_API("IsGlobalNearDeath"); |
| 463 if (!i::V8::IsRunning()) return false; | 459 if (!i::Isolate::Current()->IsInitialized()) return false; |
| 464 return i::GlobalHandles::IsNearDeath(obj); | 460 return i::GlobalHandles::IsNearDeath(obj); |
| 465 } | 461 } |
| 466 | 462 |
| 467 | 463 |
| 468 bool V8::IsGlobalWeak(i::Object** obj) { | 464 bool V8::IsGlobalWeak(i::Object** obj) { |
| 469 LOG_API("IsGlobalWeak"); | 465 LOG_API("IsGlobalWeak"); |
| 470 if (!i::V8::IsRunning()) return false; | 466 if (!i::Isolate::Current()->IsInitialized()) return false; |
| 471 return i::GlobalHandles::IsWeak(obj); | 467 return i::GlobalHandles::IsWeak(obj); |
| 472 } | 468 } |
| 473 | 469 |
| 474 | 470 |
| 475 void V8::DisposeGlobal(i::Object** obj) { | 471 void V8::DisposeGlobal(i::Object** obj) { |
| 476 LOG_API("DisposeGlobal"); | 472 LOG_API("DisposeGlobal"); |
| 477 if (!i::V8::IsRunning()) return; | 473 if (!i::Isolate::Current()->IsInitialized()) return; |
| 478 i::Isolate::Current()->global_handles()->Destroy(obj); | 474 i::Isolate::Current()->global_handles()->Destroy(obj); |
| 479 } | 475 } |
| 480 | 476 |
| 481 // --- H a n d l e s --- | 477 // --- H a n d l e s --- |
| 482 | 478 |
| 483 | 479 |
| 484 HandleScope::HandleScope() { | 480 HandleScope::HandleScope() { |
| 485 API_ENTRY_CHECK("HandleScope::HandleScope"); | 481 API_ENTRY_CHECK("HandleScope::HandleScope"); |
| 486 i::Isolate* isolate = i::Isolate::Current(); | 482 i::Isolate* isolate = i::Isolate::Current(); |
| 487 v8::ImplementationUtilities::HandleScopeData* current = | 483 v8::ImplementationUtilities::HandleScopeData* current = |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 // TODO(isolates): Context should have a pointer to isolate. | 540 // TODO(isolates): Context should have a pointer to isolate. |
| 545 i::Isolate* isolate = i::Isolate::Current(); | 541 i::Isolate* isolate = i::Isolate::Current(); |
| 546 isolate->handle_scope_implementer()->EnterContext(env); | 542 isolate->handle_scope_implementer()->EnterContext(env); |
| 547 | 543 |
| 548 isolate->handle_scope_implementer()->SaveContext(isolate->context()); | 544 isolate->handle_scope_implementer()->SaveContext(isolate->context()); |
| 549 isolate->set_context(*env); | 545 isolate->set_context(*env); |
| 550 } | 546 } |
| 551 | 547 |
| 552 | 548 |
| 553 void Context::Exit() { | 549 void Context::Exit() { |
| 554 if (!i::V8::IsRunning()) return; | 550 if (!i::Isolate::Current()->IsInitialized()) return; |
| 555 // TODO(isolates): Context should have a pointer to isolate. | 551 // TODO(isolates): Context should have a pointer to isolate. |
| 556 i::Isolate* isolate = i::Isolate::Current(); | 552 i::Isolate* isolate = i::Isolate::Current(); |
| 557 | 553 |
| 558 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(), | 554 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(), |
| 559 "v8::Context::Exit()", | 555 "v8::Context::Exit()", |
| 560 "Cannot exit non-entered context")) { | 556 "Cannot exit non-entered context")) { |
| 561 return; | 557 return; |
| 562 } | 558 } |
| 563 | 559 |
| 564 // Content of 'last_context' could be NULL. | 560 // Content of 'last_context' could be NULL. |
| (...skipping 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 return true; | 2341 return true; |
| 2346 } | 2342 } |
| 2347 | 2343 |
| 2348 | 2344 |
| 2349 bool v8::Object::ForceDelete(v8::Handle<Value> key) { | 2345 bool v8::Object::ForceDelete(v8::Handle<Value> key) { |
| 2350 ON_BAILOUT("v8::Object::ForceDelete()", return false); | 2346 ON_BAILOUT("v8::Object::ForceDelete()", return false); |
| 2351 ENTER_V8; | 2347 ENTER_V8; |
| 2352 HandleScope scope; | 2348 HandleScope scope; |
| 2353 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | 2349 i::Handle<i::JSObject> self = Utils::OpenHandle(this); |
| 2354 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | 2350 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); |
| 2351 |
| 2352 // When turning on access checks for a global object deoptimize all functions |
| 2353 // as optimized code does not always handle access checks. |
| 2354 i::Deoptimizer::DeoptimizeGlobalObject(*self); |
| 2355 |
| 2355 EXCEPTION_PREAMBLE(); | 2356 EXCEPTION_PREAMBLE(); |
| 2356 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj); | 2357 i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj); |
| 2357 has_pending_exception = obj.is_null(); | 2358 has_pending_exception = obj.is_null(); |
| 2358 EXCEPTION_BAILOUT_CHECK(false); | 2359 EXCEPTION_BAILOUT_CHECK(false); |
| 2359 return obj->IsTrue(); | 2360 return obj->IsTrue(); |
| 2360 } | 2361 } |
| 2361 | 2362 |
| 2362 | 2363 |
| 2363 Local<Value> v8::Object::Get(v8::Handle<Value> key) { | 2364 Local<Value> v8::Object::Get(v8::Handle<Value> key) { |
| 2364 ON_BAILOUT("v8::Object::Get()", return Local<v8::Value>()); | 2365 ON_BAILOUT("v8::Object::Get()", return Local<v8::Value>()); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2631 | 2632 |
| 2632 // Turns on access checks by copying the map and setting the check flag. | 2633 // Turns on access checks by copying the map and setting the check flag. |
| 2633 // Because the object gets a new map, existing inline cache caching | 2634 // Because the object gets a new map, existing inline cache caching |
| 2634 // the old map of this object will fail. | 2635 // the old map of this object will fail. |
| 2635 void v8::Object::TurnOnAccessCheck() { | 2636 void v8::Object::TurnOnAccessCheck() { |
| 2636 ON_BAILOUT("v8::Object::TurnOnAccessCheck()", return); | 2637 ON_BAILOUT("v8::Object::TurnOnAccessCheck()", return); |
| 2637 ENTER_V8; | 2638 ENTER_V8; |
| 2638 HandleScope scope; | 2639 HandleScope scope; |
| 2639 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 2640 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
| 2640 | 2641 |
| 2642 // When turning on access checks for a global object deoptimize all functions |
| 2643 // as optimized code does not always handle access checks. |
| 2644 i::Deoptimizer::DeoptimizeGlobalObject(*obj); |
| 2645 |
| 2641 i::Handle<i::Map> new_map = | 2646 i::Handle<i::Map> new_map = |
| 2642 FACTORY->CopyMapDropTransitions(i::Handle<i::Map>(obj->map())); | 2647 FACTORY->CopyMapDropTransitions(i::Handle<i::Map>(obj->map())); |
| 2643 new_map->set_is_access_check_needed(true); | 2648 new_map->set_is_access_check_needed(true); |
| 2644 obj->set_map(*new_map); | 2649 obj->set_map(*new_map); |
| 2645 } | 2650 } |
| 2646 | 2651 |
| 2647 | 2652 |
| 2648 bool v8::Object::IsDirty() { | 2653 bool v8::Object::IsDirty() { |
| 2649 return Utils::OpenHandle(this)->IsDirty(); | 2654 return Utils::OpenHandle(this)->IsDirty(); |
| 2650 } | 2655 } |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3234 if (!proxy.is_null()) | 3239 if (!proxy.is_null()) |
| 3235 Utils::OpenHandle(this)->SetInternalField(index, *proxy); | 3240 Utils::OpenHandle(this)->SetInternalField(index, *proxy); |
| 3236 } | 3241 } |
| 3237 | 3242 |
| 3238 | 3243 |
| 3239 // --- E n v i r o n m e n t --- | 3244 // --- E n v i r o n m e n t --- |
| 3240 | 3245 |
| 3241 | 3246 |
| 3242 bool v8::V8::Initialize() { | 3247 bool v8::V8::Initialize() { |
| 3243 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 3248 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
| 3244 if (isolate != NULL && isolate->IsDefaultIsolate() && i::V8::IsRunning()) { | 3249 if (isolate != NULL && isolate->IsInitialized()) { |
| 3245 return true; | 3250 return true; |
| 3246 } | 3251 } |
| 3247 ENTER_V8; | |
| 3248 return InitializeHelper(); | 3252 return InitializeHelper(); |
| 3249 } | 3253 } |
| 3250 | 3254 |
| 3251 | 3255 |
| 3252 bool v8::V8::Dispose() { | 3256 bool v8::V8::Dispose() { |
| 3253 i::Isolate* isolate = i::Isolate::Current(); | 3257 i::Isolate* isolate = i::Isolate::Current(); |
| 3254 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(), | 3258 if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(), |
| 3255 "v8::V8::Dispose()", | 3259 "v8::V8::Dispose()", |
| 3256 "Use v8::Isolate::Dispose() for a non-default isolate.")) { | 3260 "Use v8::Isolate::Dispose() for a non-default isolate.")) { |
| 3257 return false; | 3261 return false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3270 heap_statistics->set_total_heap_size(HEAP->CommittedMemory()); | 3274 heap_statistics->set_total_heap_size(HEAP->CommittedMemory()); |
| 3271 heap_statistics->set_total_heap_size_executable( | 3275 heap_statistics->set_total_heap_size_executable( |
| 3272 HEAP->CommittedMemoryExecutable()); | 3276 HEAP->CommittedMemoryExecutable()); |
| 3273 heap_statistics->set_used_heap_size(HEAP->SizeOfObjects()); | 3277 heap_statistics->set_used_heap_size(HEAP->SizeOfObjects()); |
| 3274 } | 3278 } |
| 3275 | 3279 |
| 3276 | 3280 |
| 3277 bool v8::V8::IdleNotification() { | 3281 bool v8::V8::IdleNotification() { |
| 3278 // Returning true tells the caller that it need not | 3282 // Returning true tells the caller that it need not |
| 3279 // continue to call IdleNotification. | 3283 // continue to call IdleNotification. |
| 3280 if (!i::V8::IsRunning()) return true; | 3284 if (!i::Isolate::Current()->IsInitialized()) return true; |
| 3281 return i::V8::IdleNotification(); | 3285 return i::V8::IdleNotification(); |
| 3282 } | 3286 } |
| 3283 | 3287 |
| 3284 | 3288 |
| 3285 void v8::V8::LowMemoryNotification() { | 3289 void v8::V8::LowMemoryNotification() { |
| 3286 if (!i::V8::IsRunning()) return; | 3290 if (!i::Isolate::Current()->IsInitialized()) return; |
| 3287 HEAP->CollectAllGarbage(true); | 3291 HEAP->CollectAllGarbage(true); |
| 3288 } | 3292 } |
| 3289 | 3293 |
| 3290 | 3294 |
| 3291 int v8::V8::ContextDisposedNotification() { | 3295 int v8::V8::ContextDisposedNotification() { |
| 3292 if (!i::V8::IsRunning()) return 0; | 3296 if (!i::Isolate::Current()->IsInitialized()) return 0; |
| 3293 return HEAP->NotifyContextDisposed(); | 3297 return HEAP->NotifyContextDisposed(); |
| 3294 } | 3298 } |
| 3295 | 3299 |
| 3296 | 3300 |
| 3297 const char* v8::V8::GetVersion() { | 3301 const char* v8::V8::GetVersion() { |
| 3298 return i::Version::GetVersion(); | 3302 return i::Version::GetVersion(); |
| 3299 } | 3303 } |
| 3300 | 3304 |
| 3301 | 3305 |
| 3302 static i::Handle<i::FunctionTemplateInfo> | 3306 static i::Handle<i::FunctionTemplateInfo> |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3363 | 3367 |
| 3364 // Restore the access check info on the global template. | 3368 // Restore the access check info on the global template. |
| 3365 if (!global_template.IsEmpty()) { | 3369 if (!global_template.IsEmpty()) { |
| 3366 ASSERT(!global_constructor.is_null()); | 3370 ASSERT(!global_constructor.is_null()); |
| 3367 ASSERT(!proxy_constructor.is_null()); | 3371 ASSERT(!proxy_constructor.is_null()); |
| 3368 global_constructor->set_access_check_info( | 3372 global_constructor->set_access_check_info( |
| 3369 proxy_constructor->access_check_info()); | 3373 proxy_constructor->access_check_info()); |
| 3370 global_constructor->set_needs_access_check( | 3374 global_constructor->set_needs_access_check( |
| 3371 proxy_constructor->needs_access_check()); | 3375 proxy_constructor->needs_access_check()); |
| 3372 } | 3376 } |
| 3377 i::Isolate::Current()->runtime_profiler()->Reset(); |
| 3373 } | 3378 } |
| 3374 // Leave V8. | 3379 // Leave V8. |
| 3375 | 3380 |
| 3376 if (env.is_null()) | 3381 if (env.is_null()) |
| 3377 return Persistent<Context>(); | 3382 return Persistent<Context>(); |
| 3378 return Persistent<Context>(Utils::ToLocal(env)); | 3383 return Persistent<Context>(Utils::ToLocal(env)); |
| 3379 } | 3384 } |
| 3380 | 3385 |
| 3381 | 3386 |
| 3382 void v8::Context::SetSecurityToken(Handle<Value> token) { | 3387 void v8::Context::SetSecurityToken(Handle<Value> token) { |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4130 | 4135 |
| 4131 | 4136 |
| 4132 int V8::GetCurrentThreadId() { | 4137 int V8::GetCurrentThreadId() { |
| 4133 API_ENTRY_CHECK("V8::GetCurrentThreadId()"); | 4138 API_ENTRY_CHECK("V8::GetCurrentThreadId()"); |
| 4134 EnsureInitialized("V8::GetCurrentThreadId()"); | 4139 EnsureInitialized("V8::GetCurrentThreadId()"); |
| 4135 return i::Isolate::Current()->thread_id(); | 4140 return i::Isolate::Current()->thread_id(); |
| 4136 } | 4141 } |
| 4137 | 4142 |
| 4138 | 4143 |
| 4139 void V8::TerminateExecution(int thread_id) { | 4144 void V8::TerminateExecution(int thread_id) { |
| 4140 if (!i::V8::IsRunning()) return; | 4145 if (!i::Isolate::Current()->IsInitialized()) return; |
| 4141 API_ENTRY_CHECK("V8::GetCurrentThreadId()"); | 4146 API_ENTRY_CHECK("V8::GetCurrentThreadId()"); |
| 4142 i::Isolate* isolate = i::Isolate::Current(); | 4147 i::Isolate* isolate = i::Isolate::Current(); |
| 4143 // If the thread_id identifies the current thread just terminate | 4148 // If the thread_id identifies the current thread just terminate |
| 4144 // execution right away. Otherwise, ask the thread manager to | 4149 // execution right away. Otherwise, ask the thread manager to |
| 4145 // terminate the thread with the given id if any. | 4150 // terminate the thread with the given id if any. |
| 4146 if (thread_id == isolate->thread_id()) { | 4151 if (thread_id == isolate->thread_id()) { |
| 4147 isolate->stack_guard()->TerminateExecution(); | 4152 isolate->stack_guard()->TerminateExecution(); |
| 4148 } else { | 4153 } else { |
| 4149 isolate->thread_manager()->TerminateExecution(thread_id); | 4154 isolate->thread_manager()->TerminateExecution(thread_id); |
| 4150 } | 4155 } |
| 4151 } | 4156 } |
| 4152 | 4157 |
| 4153 | 4158 |
| 4154 void V8::TerminateExecution() { | 4159 void V8::TerminateExecution() { |
| 4155 if (!i::V8::IsRunning()) return; | 4160 if (!i::Isolate::Current()->IsInitialized()) return; |
| 4156 i::Isolate::Current()->stack_guard()->TerminateExecution(); | 4161 i::Isolate::Current()->stack_guard()->TerminateExecution(); |
| 4157 } | 4162 } |
| 4158 | 4163 |
| 4159 | 4164 |
| 4160 bool V8::IsExecutionTerminating() { | 4165 bool V8::IsExecutionTerminating() { |
| 4161 if (!i::V8::IsRunning()) return false; | 4166 if (!i::Isolate::Current()->IsInitialized()) return false; |
| 4162 if (i::Isolate::Current()->has_scheduled_exception()) { | 4167 if (i::Isolate::Current()->has_scheduled_exception()) { |
| 4163 return i::Isolate::Current()->scheduled_exception() == | 4168 return i::Isolate::Current()->scheduled_exception() == |
| 4164 HEAP->termination_exception(); | 4169 HEAP->termination_exception(); |
| 4165 } | 4170 } |
| 4166 return false; | 4171 return false; |
| 4167 } | 4172 } |
| 4168 | 4173 |
| 4169 | 4174 |
| 4170 Isolate* Isolate::GetCurrent() { | 4175 Isolate* Isolate::GetCurrent() { |
| 4171 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 4176 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4412 Handle<Value> data) { | 4417 Handle<Value> data) { |
| 4413 ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false); | 4418 ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false); |
| 4414 ENTER_V8; | 4419 ENTER_V8; |
| 4415 i::Isolate::Current()->debugger()->SetEventListener(Utils::OpenHandle(*that), | 4420 i::Isolate::Current()->debugger()->SetEventListener(Utils::OpenHandle(*that), |
| 4416 Utils::OpenHandle(*data)); | 4421 Utils::OpenHandle(*data)); |
| 4417 return true; | 4422 return true; |
| 4418 } | 4423 } |
| 4419 | 4424 |
| 4420 | 4425 |
| 4421 void Debug::DebugBreak() { | 4426 void Debug::DebugBreak() { |
| 4422 if (!i::V8::IsRunning()) return; | 4427 if (!i::Isolate::Current()->IsInitialized()) return; |
| 4423 i::Isolate::Current()->stack_guard()->DebugBreak(); | 4428 i::Isolate::Current()->stack_guard()->DebugBreak(); |
| 4424 } | 4429 } |
| 4425 | 4430 |
| 4426 | 4431 |
| 4427 void Debug::CancelDebugBreak() { | 4432 void Debug::CancelDebugBreak() { |
| 4428 i::Isolate::Current()->stack_guard()->Continue(i::DEBUGBREAK); | 4433 i::Isolate::Current()->stack_guard()->Continue(i::DEBUGBREAK); |
| 4429 } | 4434 } |
| 4430 | 4435 |
| 4431 | 4436 |
| 4432 void Debug::DebugBreakForCommand(ClientData* data) { | 4437 void Debug::DebugBreakForCommand(ClientData* data) { |
| 4433 if (!i::V8::IsRunning()) return; | 4438 if (!i::Isolate::Current()->IsInitialized()) return; |
| 4434 i::Isolate::Current()->debugger()->EnqueueDebugCommand(data); | 4439 i::Isolate::Current()->debugger()->EnqueueDebugCommand(data); |
| 4435 } | 4440 } |
| 4436 | 4441 |
| 4437 | 4442 |
| 4438 static void MessageHandlerWrapper(const v8::Debug::Message& message) { | 4443 static void MessageHandlerWrapper(const v8::Debug::Message& message) { |
| 4439 i::Isolate* isolate = i::Isolate::Current(); | 4444 i::Isolate* isolate = i::Isolate::Current(); |
| 4440 if (isolate->message_handler()) { | 4445 if (isolate->message_handler()) { |
| 4441 v8::String::Value json(message.GetJSON()); | 4446 v8::String::Value json(message.GetJSON()); |
| 4442 (isolate->message_handler())(*json, json.length(), message.GetClientData()); | 4447 (isolate->message_handler())(*json, json.length(), message.GetClientData()); |
| 4443 } | 4448 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4465 | 4470 |
| 4466 void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) { | 4471 void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) { |
| 4467 EnsureInitialized("v8::Debug::SetMessageHandler"); | 4472 EnsureInitialized("v8::Debug::SetMessageHandler"); |
| 4468 ENTER_V8; | 4473 ENTER_V8; |
| 4469 i::Isolate::Current()->debugger()->SetMessageHandler(handler); | 4474 i::Isolate::Current()->debugger()->SetMessageHandler(handler); |
| 4470 } | 4475 } |
| 4471 | 4476 |
| 4472 | 4477 |
| 4473 void Debug::SendCommand(const uint16_t* command, int length, | 4478 void Debug::SendCommand(const uint16_t* command, int length, |
| 4474 ClientData* client_data) { | 4479 ClientData* client_data) { |
| 4475 if (!i::V8::IsRunning()) return; | 4480 if (!i::Isolate::Current()->IsInitialized()) return; |
| 4476 i::Isolate::Current()->debugger()->ProcessCommand( | 4481 i::Isolate::Current()->debugger()->ProcessCommand( |
| 4477 i::Vector<const uint16_t>(command, length), client_data); | 4482 i::Vector<const uint16_t>(command, length), client_data); |
| 4478 } | 4483 } |
| 4479 | 4484 |
| 4480 | 4485 |
| 4481 void Debug::SetHostDispatchHandler(HostDispatchHandler handler, | 4486 void Debug::SetHostDispatchHandler(HostDispatchHandler handler, |
| 4482 int period) { | 4487 int period) { |
| 4483 EnsureInitialized("v8::Debug::SetHostDispatchHandler"); | 4488 EnsureInitialized("v8::Debug::SetHostDispatchHandler"); |
| 4484 ENTER_V8; | 4489 ENTER_V8; |
| 4485 i::Isolate::Current()->debugger()->SetHostDispatchHandler(handler, period); | 4490 i::Isolate::Current()->debugger()->SetHostDispatchHandler(handler, period); |
| 4486 } | 4491 } |
| 4487 | 4492 |
| 4488 | 4493 |
| 4489 void Debug::SetDebugMessageDispatchHandler( | 4494 void Debug::SetDebugMessageDispatchHandler( |
| 4490 DebugMessageDispatchHandler handler, bool provide_locker) { | 4495 DebugMessageDispatchHandler handler, bool provide_locker) { |
| 4491 EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler"); | 4496 EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler"); |
| 4492 ENTER_V8; | 4497 ENTER_V8; |
| 4493 i::Isolate::Current()->debugger()->SetDebugMessageDispatchHandler( | 4498 i::Isolate::Current()->debugger()->SetDebugMessageDispatchHandler( |
| 4494 handler, provide_locker); | 4499 handler, provide_locker); |
| 4495 } | 4500 } |
| 4496 | 4501 |
| 4497 | 4502 |
| 4498 Local<Value> Debug::Call(v8::Handle<v8::Function> fun, | 4503 Local<Value> Debug::Call(v8::Handle<v8::Function> fun, |
| 4499 v8::Handle<v8::Value> data) { | 4504 v8::Handle<v8::Value> data) { |
| 4500 if (!i::V8::IsRunning()) return Local<Value>(); | 4505 if (!i::Isolate::Current()->IsInitialized()) return Local<Value>(); |
| 4501 ON_BAILOUT("v8::Debug::Call()", return Local<Value>()); | 4506 ON_BAILOUT("v8::Debug::Call()", return Local<Value>()); |
| 4502 ENTER_V8; | 4507 ENTER_V8; |
| 4503 i::Handle<i::Object> result; | 4508 i::Handle<i::Object> result; |
| 4504 EXCEPTION_PREAMBLE(); | 4509 EXCEPTION_PREAMBLE(); |
| 4505 if (data.IsEmpty()) { | 4510 if (data.IsEmpty()) { |
| 4506 result = | 4511 result = |
| 4507 i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun), | 4512 i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun), |
| 4508 FACTORY->undefined_value(), | 4513 FACTORY->undefined_value(), |
| 4509 &has_pending_exception); | 4514 &has_pending_exception); |
| 4510 } else { | 4515 } else { |
| 4511 result = i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun), | 4516 result = i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun), |
| 4512 Utils::OpenHandle(*data), | 4517 Utils::OpenHandle(*data), |
| 4513 &has_pending_exception); | 4518 &has_pending_exception); |
| 4514 } | 4519 } |
| 4515 EXCEPTION_BAILOUT_CHECK(Local<Value>()); | 4520 EXCEPTION_BAILOUT_CHECK(Local<Value>()); |
| 4516 return Utils::ToLocal(result); | 4521 return Utils::ToLocal(result); |
| 4517 } | 4522 } |
| 4518 | 4523 |
| 4519 | 4524 |
| 4520 Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) { | 4525 Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) { |
| 4521 if (!i::V8::IsRunning()) return Local<Value>(); | 4526 if (!i::Isolate::Current()->IsInitialized()) return Local<Value>(); |
| 4522 ON_BAILOUT("v8::Debug::GetMirror()", return Local<Value>()); | 4527 ON_BAILOUT("v8::Debug::GetMirror()", return Local<Value>()); |
| 4523 ENTER_V8; | 4528 ENTER_V8; |
| 4524 v8::HandleScope scope; | 4529 v8::HandleScope scope; |
| 4525 i::Debug* isolate_debug = i::Isolate::Current()->debug(); | 4530 i::Debug* isolate_debug = i::Isolate::Current()->debug(); |
| 4526 isolate_debug->Load(); | 4531 isolate_debug->Load(); |
| 4527 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global()); | 4532 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global()); |
| 4528 i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("MakeMirror"); | 4533 i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("MakeMirror"); |
| 4529 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name); | 4534 i::Handle<i::Object> fun_obj = i::GetProperty(debug, name); |
| 4530 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj); | 4535 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj); |
| 4531 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun); | 4536 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun); |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4982 default: | 4987 default: |
| 4983 UNREACHABLE(); | 4988 UNREACHABLE(); |
| 4984 } | 4989 } |
| 4985 return reinterpret_cast<const HeapSnapshot*>( | 4990 return reinterpret_cast<const HeapSnapshot*>( |
| 4986 i::HeapProfiler::TakeSnapshot(*Utils::OpenHandle(*title), internal_type)); | 4991 i::HeapProfiler::TakeSnapshot(*Utils::OpenHandle(*title), internal_type)); |
| 4987 } | 4992 } |
| 4988 | 4993 |
| 4989 #endif // ENABLE_LOGGING_AND_PROFILING | 4994 #endif // ENABLE_LOGGING_AND_PROFILING |
| 4990 | 4995 |
| 4991 | 4996 |
| 4997 v8::Testing::StressType internal::Testing::stress_type_ = |
| 4998 v8::Testing::kStressTypeOpt; |
| 4999 |
| 5000 |
| 5001 void Testing::SetStressRunType(Testing::StressType type) { |
| 5002 internal::Testing::set_stress_type(type); |
| 5003 } |
| 5004 |
| 5005 int Testing::GetStressRuns() { |
| 5006 #ifdef DEBUG |
| 5007 // In debug mode the code runs much slower so stressing will only make two |
| 5008 // runs. |
| 5009 return 2; |
| 5010 #else |
| 5011 return 5; |
| 5012 #endif |
| 5013 } |
| 5014 |
| 5015 |
| 5016 static void SetFlagsFromString(const char* flags) { |
| 5017 V8::SetFlagsFromString(flags, i::StrLength(flags)); |
| 5018 } |
| 5019 |
| 5020 |
| 5021 void Testing::PrepareStressRun(int run) { |
| 5022 static const char* kLazyOptimizations = |
| 5023 "--prepare-always-opt --nolimit-inlining " |
| 5024 "--noalways-opt --noopt-eagerly"; |
| 5025 static const char* kEagerOptimizations = "--opt-eagerly"; |
| 5026 static const char* kForcedOptimizations = "--always-opt"; |
| 5027 |
| 5028 // If deoptimization stressed turn on frequent deoptimization. If no value |
| 5029 // is spefified through --deopt-every-n-times use a default default value. |
| 5030 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13"; |
| 5031 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt && |
| 5032 internal::FLAG_deopt_every_n_times == 0) { |
| 5033 SetFlagsFromString(kDeoptEvery13Times); |
| 5034 } |
| 5035 |
| 5036 #ifdef DEBUG |
| 5037 // As stressing in debug mode only make two runs skip the deopt stressing |
| 5038 // here. |
| 5039 if (run == GetStressRuns() - 1) { |
| 5040 SetFlagsFromString(kForcedOptimizations); |
| 5041 } else { |
| 5042 SetFlagsFromString(kEagerOptimizations); |
| 5043 SetFlagsFromString(kLazyOptimizations); |
| 5044 } |
| 5045 #else |
| 5046 if (run == GetStressRuns() - 1) { |
| 5047 SetFlagsFromString(kForcedOptimizations); |
| 5048 } else if (run == GetStressRuns() - 2) { |
| 5049 SetFlagsFromString(kEagerOptimizations); |
| 5050 } else { |
| 5051 SetFlagsFromString(kLazyOptimizations); |
| 5052 } |
| 5053 #endif |
| 5054 } |
| 5055 |
| 5056 |
| 4992 namespace internal { | 5057 namespace internal { |
| 4993 | 5058 |
| 4994 | 5059 |
| 4995 void HandleScopeImplementer::FreeThreadResources() { | 5060 void HandleScopeImplementer::FreeThreadResources() { |
| 4996 Free(); | 5061 Free(); |
| 4997 } | 5062 } |
| 4998 | 5063 |
| 4999 | 5064 |
| 5000 char* HandleScopeImplementer::ArchiveThread(char* storage) { | 5065 char* HandleScopeImplementer::ArchiveThread(char* storage) { |
| 5001 Isolate* isolate = Isolate::Current(); | 5066 Isolate* isolate = Isolate::Current(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5051 | 5116 |
| 5052 | 5117 |
| 5053 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { | 5118 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { |
| 5054 HandleScopeImplementer* thread_local = | 5119 HandleScopeImplementer* thread_local = |
| 5055 reinterpret_cast<HandleScopeImplementer*>(storage); | 5120 reinterpret_cast<HandleScopeImplementer*>(storage); |
| 5056 thread_local->IterateThis(v); | 5121 thread_local->IterateThis(v); |
| 5057 return storage + ArchiveSpacePerThread(); | 5122 return storage + ArchiveSpacePerThread(); |
| 5058 } | 5123 } |
| 5059 | 5124 |
| 5060 } } // namespace v8::internal | 5125 } } // namespace v8::internal |
| OLD | NEW |