| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 | 57 |
| 58 #define ON_BAILOUT(location, code) \ | 58 #define ON_BAILOUT(location, code) \ |
| 59 if (IsDeadCheck(location)) { \ | 59 if (IsDeadCheck(location)) { \ |
| 60 code; \ | 60 code; \ |
| 61 UNREACHABLE(); \ | 61 UNREACHABLE(); \ |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 #define EXCEPTION_PREAMBLE() \ | 65 #define EXCEPTION_PREAMBLE() \ |
| 66 thread_local.IncrementCallDepth(); \ | 66 v8_context()->handle_scope_implementer_.IncrementCallDepth(); \ |
| 67 ASSERT(!i::Top::external_caught_exception()); \ | 67 ASSERT(!i::Top::external_caught_exception()); \ |
| 68 bool has_pending_exception = false | 68 bool has_pending_exception = false |
| 69 | 69 |
| 70 | 70 |
| 71 #define EXCEPTION_BAILOUT_CHECK(value) \ | 71 #define EXCEPTION_BAILOUT_CHECK(value) \ |
| 72 do { \ | 72 do { \ |
| 73 i::HandleScopeImplementer& thread_local = \ |
| 74 v8_context()->handle_scope_implementer_; \ |
| 73 thread_local.DecrementCallDepth(); \ | 75 thread_local.DecrementCallDepth(); \ |
| 74 if (has_pending_exception) { \ | 76 if (has_pending_exception) { \ |
| 75 if (thread_local.CallDepthIsZero() && i::Top::is_out_of_memory()) { \ | 77 if (thread_local.CallDepthIsZero() && i::Top::is_out_of_memory()) { \ |
| 76 if (!thread_local.ignore_out_of_memory()) \ | 78 if (!thread_local.ignore_out_of_memory()) \ |
| 77 i::V8::FatalProcessOutOfMemory(NULL); \ | 79 i::V8::FatalProcessOutOfMemory(NULL); \ |
| 78 } \ | 80 } \ |
| 79 bool call_depth_is_zero = thread_local.CallDepthIsZero(); \ | 81 bool call_depth_is_zero = thread_local.CallDepthIsZero(); \ |
| 80 i::Top::OptionalRescheduleException(call_depth_is_zero); \ | 82 i::Top::OptionalRescheduleException(call_depth_is_zero); \ |
| 81 return value; \ | 83 return value; \ |
| 82 } \ | 84 } \ |
| 83 } while (false) | 85 } while (false) |
| 84 | 86 |
| 85 | 87 |
| 86 #define API_ENTRY_CHECK(msg) \ | 88 #define API_ENTRY_CHECK(msg) \ |
| 87 do { \ | 89 do { \ |
| 88 if (v8::Locker::IsActive()) { \ | 90 if (v8::Locker::IsActive()) { \ |
| 89 ApiCheck(i::ThreadManager::IsLockedByCurrentThread(), \ | 91 ApiCheck(i::ThreadManager::IsLockedByCurrentThread(), \ |
| 90 msg, \ | 92 msg, \ |
| 91 "Entering the V8 API without proper locking in place"); \ | 93 "Entering the V8 API without proper locking in place"); \ |
| 92 } \ | 94 } \ |
| 93 } while (false) | 95 } while (false) |
| 94 | 96 |
| 95 // --- D a t a t h a t i s s p e c i f i c t o a t h r e a d --- | 97 // --- D a t a t h a t i s s p e c i f i c t o a t h r e a d --- |
| 96 | 98 |
| 97 | 99 |
| 98 static i::HandleScopeImplementer thread_local; | |
| 99 | 100 |
| 100 | 101 |
| 101 // --- E x c e p t i o n B e h a v i o r --- | |
| 102 | 102 |
| 103 | 103 |
| 104 static FatalErrorCallback exception_behavior = NULL; | 104 |
| 105 int i::Internals::kJSObjectType = JS_OBJECT_TYPE; | 105 int i::Internals::kJSObjectType = JS_OBJECT_TYPE; |
| 106 int i::Internals::kFirstNonstringType = FIRST_NONSTRING_TYPE; | 106 int i::Internals::kFirstNonstringType = FIRST_NONSTRING_TYPE; |
| 107 int i::Internals::kProxyType = PROXY_TYPE; | 107 int i::Internals::kProxyType = PROXY_TYPE; |
| 108 | 108 |
| 109 static void DefaultFatalErrorHandler(const char* location, | 109 static void DefaultFatalErrorHandler(const char* location, |
| 110 const char* message) { | 110 const char* message) { |
| 111 ENTER_V8; | 111 ENTER_V8; |
| 112 API_Fatal(location, message); | 112 API_Fatal(location, message); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 | 116 |
| 117 static FatalErrorCallback& GetFatalErrorHandler() { | 117 static FatalErrorCallback GetFatalErrorHandler() { |
| 118 if (exception_behavior == NULL) { | 118 internal::V8Data& v8_data = v8_context()->v8_data_; |
| 119 exception_behavior = DefaultFatalErrorHandler; | 119 if (v8_data.exception_behavior() == NULL) { |
| 120 v8_data.exception_behavior(DefaultFatalErrorHandler); |
| 120 } | 121 } |
| 121 return exception_behavior; | 122 return v8_data.exception_behavior(); |
| 122 } | 123 } |
| 123 | 124 |
| 124 | 125 |
| 125 | 126 |
| 126 // When V8 cannot allocated memory FatalProcessOutOfMemory is called. | 127 // When V8 cannot allocated memory FatalProcessOutOfMemory is called. |
| 127 // The default fatal error handler is called and execution is stopped. | 128 // The default fatal error handler is called and execution is stopped. |
| 128 void i::V8::FatalProcessOutOfMemory(const char* location) { | 129 void i::V8::FatalProcessOutOfMemory(const char* location) { |
| 129 i::HeapStats heap_stats; | 130 i::HeapStats heap_stats; |
| 130 int start_marker; | 131 int start_marker; |
| 131 heap_stats.start_marker = &start_marker; | 132 heap_stats.start_marker = &start_marker; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 { | 174 { |
| 174 LEAVE_V8; | 175 LEAVE_V8; |
| 175 callback(location, "Allocation failed - process out of memory"); | 176 callback(location, "Allocation failed - process out of memory"); |
| 176 } | 177 } |
| 177 // If the callback returns, we stop execution. | 178 // If the callback returns, we stop execution. |
| 178 UNREACHABLE(); | 179 UNREACHABLE(); |
| 179 } | 180 } |
| 180 | 181 |
| 181 | 182 |
| 182 void V8::SetFatalErrorHandler(FatalErrorCallback that) { | 183 void V8::SetFatalErrorHandler(FatalErrorCallback that) { |
| 183 exception_behavior = that; | 184 v8_context()->v8_data_.exception_behavior(that); |
| 184 } | 185 } |
| 185 | 186 |
| 186 | 187 |
| 187 bool Utils::ReportApiFailure(const char* location, const char* message) { | 188 bool Utils::ReportApiFailure(const char* location, const char* message) { |
| 188 FatalErrorCallback callback = GetFatalErrorHandler(); | 189 FatalErrorCallback callback = GetFatalErrorHandler(); |
| 189 callback(location, message); | 190 callback(location, message); |
| 190 i::V8::SetFatalError(); | 191 i::V8::SetFatalError(); |
| 191 return false; | 192 return false; |
| 192 } | 193 } |
| 193 | 194 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 } | 242 } |
| 242 | 243 |
| 243 | 244 |
| 244 static inline bool EmptyCheck(const char* location, const v8::Data* obj) { | 245 static inline bool EmptyCheck(const char* location, const v8::Data* obj) { |
| 245 return (obj == 0) ? ReportEmptyHandle(location) : false; | 246 return (obj == 0) ? ReportEmptyHandle(location) : false; |
| 246 } | 247 } |
| 247 | 248 |
| 248 // --- S t a t i c s --- | 249 // --- S t a t i c s --- |
| 249 | 250 |
| 250 | 251 |
| 251 static i::StringInputBuffer write_input_buffer; | |
| 252 | 252 |
| 253 | 253 |
| 254 static inline bool EnsureInitialized(const char* location) { | 254 static inline bool EnsureInitialized(const char* location) { |
| 255 if (i::V8::IsRunning()) { | 255 if (i::V8::IsRunning()) { |
| 256 return true; | 256 return true; |
| 257 } | 257 } |
| 258 if (IsDeadCheck(location)) { | 258 if (IsDeadCheck(location)) { |
| 259 return false; | 259 return false; |
| 260 } | 260 } |
| 261 return ApiCheck(v8::V8::Initialize(), location, "Error initializing V8"); | 261 return ApiCheck(v8::V8::Initialize(), location, "Error initializing V8"); |
| 262 } | 262 } |
| 263 | 263 |
| 264 | 264 |
| 265 ImplementationUtilities::HandleScopeData* | 265 ImplementationUtilities::HandleScopeData* |
| 266 ImplementationUtilities::CurrentHandleScope() { | 266 ImplementationUtilities::CurrentHandleScope() { |
| 267 return &i::HandleScope::current_; | 267 return &v8_context()->handle_scope_data_; |
| 268 } | 268 } |
| 269 | 269 |
| 270 | 270 |
| 271 #ifdef DEBUG | 271 #ifdef DEBUG |
| 272 void ImplementationUtilities::ZapHandleRange(i::Object** begin, | 272 void ImplementationUtilities::ZapHandleRange(i::Object** begin, |
| 273 i::Object** end) { | 273 i::Object** end) { |
| 274 i::HandleScope::ZapRange(begin, end); | 274 i::HandleScope::ZapRange(begin, end); |
| 275 } | 275 } |
| 276 #endif | 276 #endif |
| 277 | 277 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 i::Top::ScheduleThrow(i::Heap::undefined_value()); | 319 i::Top::ScheduleThrow(i::Heap::undefined_value()); |
| 320 } else { | 320 } else { |
| 321 i::Top::ScheduleThrow(*Utils::OpenHandle(*value)); | 321 i::Top::ScheduleThrow(*Utils::OpenHandle(*value)); |
| 322 } | 322 } |
| 323 return v8::Undefined(); | 323 return v8::Undefined(); |
| 324 } | 324 } |
| 325 | 325 |
| 326 | 326 |
| 327 RegisteredExtension* RegisteredExtension::first_extension_ = NULL; | 327 RegisteredExtension* RegisteredExtension::first_extension_ = NULL; |
| 328 | 328 |
| 329 | |
| 330 RegisteredExtension::RegisteredExtension(Extension* extension) | 329 RegisteredExtension::RegisteredExtension(Extension* extension) |
| 331 : extension_(extension), state_(UNVISITED) { } | 330 : extension_(extension), state_(UNVISITED) { } |
| 332 | 331 |
| 333 | 332 |
| 334 void RegisteredExtension::Register(RegisteredExtension* that) { | 333 void RegisteredExtension::Register(RegisteredExtension* that) { |
| 335 that->next_ = RegisteredExtension::first_extension_; | 334 that->next_ = RegisteredExtension::first_extension_; |
| 336 RegisteredExtension::first_extension_ = that; | 335 RegisteredExtension::first_extension_ = that; |
| 337 } | 336 } |
| 338 | 337 |
| 339 | |
| 340 void RegisterExtension(Extension* that) { | 338 void RegisterExtension(Extension* that) { |
| 341 RegisteredExtension* extension = new RegisteredExtension(that); | 339 RegisteredExtension* extension = new RegisteredExtension(that); |
| 342 RegisteredExtension::Register(extension); | 340 RegisteredExtension::Register(extension); |
| 343 } | 341 } |
| 344 | 342 |
| 345 | 343 |
| 346 Extension::Extension(const char* name, | 344 Extension::Extension(const char* name, |
| 347 const char* source, | 345 const char* source, |
| 348 int dep_count, | 346 int dep_count, |
| 349 const char** deps) | 347 const char** deps) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 | 463 |
| 466 i::Object** v8::HandleScope::CreateHandle(i::Object* value) { | 464 i::Object** v8::HandleScope::CreateHandle(i::Object* value) { |
| 467 return i::HandleScope::CreateHandle(value); | 465 return i::HandleScope::CreateHandle(value); |
| 468 } | 466 } |
| 469 | 467 |
| 470 | 468 |
| 471 void Context::Enter() { | 469 void Context::Enter() { |
| 472 if (IsDeadCheck("v8::Context::Enter()")) return; | 470 if (IsDeadCheck("v8::Context::Enter()")) return; |
| 473 ENTER_V8; | 471 ENTER_V8; |
| 474 i::Handle<i::Context> env = Utils::OpenHandle(this); | 472 i::Handle<i::Context> env = Utils::OpenHandle(this); |
| 473 i::HandleScopeImplementer& thread_local = |
| 474 v8_context()->handle_scope_implementer_; |
| 475 thread_local.EnterContext(env); | 475 thread_local.EnterContext(env); |
| 476 | 476 |
| 477 thread_local.SaveContext(i::Top::context()); | 477 thread_local.SaveContext(i::Top::context()); |
| 478 i::Top::set_context(*env); | 478 i::Top::set_context(*env); |
| 479 } | 479 } |
| 480 | 480 |
| 481 | 481 |
| 482 void Context::Exit() { | 482 void Context::Exit() { |
| 483 if (!i::V8::IsRunning()) return; | 483 if (!i::V8::IsRunning()) return; |
| 484 i::HandleScopeImplementer& thread_local = |
| 485 v8_context()->handle_scope_implementer_; |
| 484 if (!ApiCheck(thread_local.LeaveLastContext(), | 486 if (!ApiCheck(thread_local.LeaveLastContext(), |
| 485 "v8::Context::Exit()", | 487 "v8::Context::Exit()", |
| 486 "Cannot exit non-entered context")) { | 488 "Cannot exit non-entered context")) { |
| 487 return; | 489 return; |
| 488 } | 490 } |
| 489 | 491 |
| 490 // Content of 'last_context' could be NULL. | 492 // Content of 'last_context' could be NULL. |
| 491 i::Context* last_context = thread_local.RestoreContext(); | 493 i::Context* last_context = thread_local.RestoreContext(); |
| 492 i::Top::set_context(last_context); | 494 i::Top::set_context(last_context); |
| 493 } | 495 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 } | 659 } |
| 658 | 660 |
| 659 | 661 |
| 660 void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) { | 662 void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) { |
| 661 if (IsDeadCheck("v8::FunctionTemplate::Inherit()")) return; | 663 if (IsDeadCheck("v8::FunctionTemplate::Inherit()")) return; |
| 662 ENTER_V8; | 664 ENTER_V8; |
| 663 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value)); | 665 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value)); |
| 664 } | 666 } |
| 665 | 667 |
| 666 | 668 |
| 667 // To distinguish the function templates, so that we can find them in the | |
| 668 // function cache of the global context. | |
| 669 static int next_serial_number = 0; | |
| 670 | 669 |
| 671 | 670 |
| 672 Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback, | 671 Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback, |
| 673 v8::Handle<Value> data, v8::Handle<Signature> signature) { | 672 v8::Handle<Value> data, v8::Handle<Signature> signature) { |
| 674 EnsureInitialized("v8::FunctionTemplate::New()"); | 673 EnsureInitialized("v8::FunctionTemplate::New()"); |
| 675 LOG_API("FunctionTemplate::New"); | 674 LOG_API("FunctionTemplate::New"); |
| 676 ENTER_V8; | 675 ENTER_V8; |
| 677 i::Handle<i::Struct> struct_obj = | 676 i::Handle<i::Struct> struct_obj = |
| 678 i::Factory::NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE); | 677 i::Factory::NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE); |
| 679 i::Handle<i::FunctionTemplateInfo> obj = | 678 i::Handle<i::FunctionTemplateInfo> obj = |
| 680 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj); | 679 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj); |
| 681 InitializeFunctionTemplate(obj); | 680 InitializeFunctionTemplate(obj); |
| 682 obj->set_serial_number(i::Smi::FromInt(next_serial_number++)); | 681 obj->set_serial_number(i::Smi::FromInt( |
| 682 v8_context()->api_data_.next_serial_number_++)); |
| 683 if (callback != 0) { | 683 if (callback != 0) { |
| 684 if (data.IsEmpty()) data = v8::Undefined(); | 684 if (data.IsEmpty()) data = v8::Undefined(); |
| 685 Utils::ToLocal(obj)->SetCallHandler(callback, data); | 685 Utils::ToLocal(obj)->SetCallHandler(callback, data); |
| 686 } | 686 } |
| 687 obj->set_undetectable(false); | 687 obj->set_undetectable(false); |
| 688 obj->set_needs_access_check(false); | 688 obj->set_needs_access_check(false); |
| 689 | 689 |
| 690 if (!signature.IsEmpty()) | 690 if (!signature.IsEmpty()) |
| 691 obj->set_signature(*Utils::OpenHandle(*signature)); | 691 obj->set_signature(*Utils::OpenHandle(*signature)); |
| 692 return Utils::ToLocal(obj); | 692 return Utils::ToLocal(obj); |
| (...skipping 1762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2455 if (IsDeadCheck("v8::String::Utf8Length()")) return 0; | 2455 if (IsDeadCheck("v8::String::Utf8Length()")) return 0; |
| 2456 return Utils::OpenHandle(this)->Utf8Length(); | 2456 return Utils::OpenHandle(this)->Utf8Length(); |
| 2457 } | 2457 } |
| 2458 | 2458 |
| 2459 | 2459 |
| 2460 int String::WriteUtf8(char* buffer, int capacity) const { | 2460 int String::WriteUtf8(char* buffer, int capacity) const { |
| 2461 if (IsDeadCheck("v8::String::WriteUtf8()")) return 0; | 2461 if (IsDeadCheck("v8::String::WriteUtf8()")) return 0; |
| 2462 LOG_API("String::WriteUtf8"); | 2462 LOG_API("String::WriteUtf8"); |
| 2463 ENTER_V8; | 2463 ENTER_V8; |
| 2464 i::Handle<i::String> str = Utils::OpenHandle(this); | 2464 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 2465 i::StringInputBuffer& write_input_buffer = |
| 2466 v8_context()->api_data_.write_input_buffer_; |
| 2465 write_input_buffer.Reset(0, *str); | 2467 write_input_buffer.Reset(0, *str); |
| 2466 int len = str->length(); | 2468 int len = str->length(); |
| 2467 // Encode the first K - 3 bytes directly into the buffer since we | 2469 // Encode the first K - 3 bytes directly into the buffer since we |
| 2468 // know there's room for them. If no capacity is given we copy all | 2470 // know there's room for them. If no capacity is given we copy all |
| 2469 // of them here. | 2471 // of them here. |
| 2470 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1); | 2472 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1); |
| 2471 int i; | 2473 int i; |
| 2472 int pos = 0; | 2474 int pos = 0; |
| 2473 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) { | 2475 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) { |
| 2474 i::uc32 c = write_input_buffer.GetNext(); | 2476 i::uc32 c = write_input_buffer.GetNext(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2505 ENTER_V8; | 2507 ENTER_V8; |
| 2506 ASSERT(start >= 0 && length >= -1); | 2508 ASSERT(start >= 0 && length >= -1); |
| 2507 i::Handle<i::String> str = Utils::OpenHandle(this); | 2509 i::Handle<i::String> str = Utils::OpenHandle(this); |
| 2508 // Flatten the string for efficiency. This applies whether we are | 2510 // Flatten the string for efficiency. This applies whether we are |
| 2509 // using StringInputBuffer or Get(i) to access the characters. | 2511 // using StringInputBuffer or Get(i) to access the characters. |
| 2510 str->TryFlattenIfNotFlat(); | 2512 str->TryFlattenIfNotFlat(); |
| 2511 int end = length; | 2513 int end = length; |
| 2512 if ( (length == -1) || (length > str->length() - start) ) | 2514 if ( (length == -1) || (length > str->length() - start) ) |
| 2513 end = str->length() - start; | 2515 end = str->length() - start; |
| 2514 if (end < 0) return 0; | 2516 if (end < 0) return 0; |
| 2517 i::StringInputBuffer& write_input_buffer = v8_context()->api_data_. |
| 2518 write_input_buffer_; |
| 2515 write_input_buffer.Reset(start, *str); | 2519 write_input_buffer.Reset(start, *str); |
| 2516 int i; | 2520 int i; |
| 2517 for (i = 0; i < end; i++) { | 2521 for (i = 0; i < end; i++) { |
| 2518 char c = static_cast<char>(write_input_buffer.GetNext()); | 2522 char c = static_cast<char>(write_input_buffer.GetNext()); |
| 2519 if (c == '\0') c = ' '; | 2523 if (c == '\0') c = ' '; |
| 2520 buffer[i] = c; | 2524 buffer[i] = c; |
| 2521 } | 2525 } |
| 2522 if (length == -1 || i < length) | 2526 if (length == -1 || i < length) |
| 2523 buffer[i] = '\0'; | 2527 buffer[i] = '\0'; |
| 2524 return i; | 2528 return i; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2706 } | 2710 } |
| 2707 | 2711 |
| 2708 | 2712 |
| 2709 void v8::V8::LowMemoryNotification() { | 2713 void v8::V8::LowMemoryNotification() { |
| 2710 if (!i::V8::IsRunning()) return; | 2714 if (!i::V8::IsRunning()) return; |
| 2711 i::Heap::CollectAllGarbage(true); | 2715 i::Heap::CollectAllGarbage(true); |
| 2712 } | 2716 } |
| 2713 | 2717 |
| 2714 | 2718 |
| 2715 const char* v8::V8::GetVersion() { | 2719 const char* v8::V8::GetVersion() { |
| 2716 static v8::internal::EmbeddedVector<char, 128> buffer; | 2720 v8::internal::EmbeddedVector<char, 128>& buffer = |
| 2721 v8_context()->api_data_.buffer_; |
| 2717 v8::internal::Version::GetString(buffer); | 2722 v8::internal::Version::GetString(buffer); |
| 2718 return buffer.start(); | 2723 return buffer.start(); |
| 2719 } | 2724 } |
| 2720 | 2725 |
| 2721 | 2726 |
| 2722 static i::Handle<i::FunctionTemplateInfo> | 2727 static i::Handle<i::FunctionTemplateInfo> |
| 2723 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) { | 2728 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) { |
| 2724 if (templ->constructor()->IsUndefined()) { | 2729 if (templ->constructor()->IsUndefined()) { |
| 2725 Local<FunctionTemplate> constructor = FunctionTemplate::New(); | 2730 Local<FunctionTemplate> constructor = FunctionTemplate::New(); |
| 2726 Utils::OpenHandle(*constructor)->set_instance_template(*templ); | 2731 Utils::OpenHandle(*constructor)->set_instance_template(*templ); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2838 } | 2843 } |
| 2839 | 2844 |
| 2840 | 2845 |
| 2841 bool Context::InContext() { | 2846 bool Context::InContext() { |
| 2842 return i::Top::context() != NULL; | 2847 return i::Top::context() != NULL; |
| 2843 } | 2848 } |
| 2844 | 2849 |
| 2845 | 2850 |
| 2846 v8::Local<v8::Context> Context::GetEntered() { | 2851 v8::Local<v8::Context> Context::GetEntered() { |
| 2847 if (IsDeadCheck("v8::Context::GetEntered()")) return Local<Context>(); | 2852 if (IsDeadCheck("v8::Context::GetEntered()")) return Local<Context>(); |
| 2848 i::Handle<i::Object> last = thread_local.LastEnteredContext(); | 2853 i::Handle<i::Object> last = |
| 2854 v8_context()->handle_scope_implementer_.LastEnteredContext(); |
| 2849 if (last.is_null()) return Local<Context>(); | 2855 if (last.is_null()) return Local<Context>(); |
| 2850 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last); | 2856 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last); |
| 2851 return Utils::ToLocal(context); | 2857 return Utils::ToLocal(context); |
| 2852 } | 2858 } |
| 2853 | 2859 |
| 2854 | 2860 |
| 2855 v8::Local<v8::Context> Context::GetCurrent() { | 2861 v8::Local<v8::Context> Context::GetCurrent() { |
| 2856 if (IsDeadCheck("v8::Context::GetCurrent()")) return Local<Context>(); | 2862 if (IsDeadCheck("v8::Context::GetCurrent()")) return Local<Context>(); |
| 2857 i::Handle<i::Object> current = i::Top::global_context(); | 2863 i::Handle<i::Object> current = i::Top::global_context(); |
| 2858 if (current.is_null()) return Local<Context>(); | 2864 if (current.is_null()) return Local<Context>(); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 | 3096 |
| 3091 // External symbols are deleted when they are pruned out of the symbol | 3097 // External symbols are deleted when they are pruned out of the symbol |
| 3092 // table. Generally external symbols are not registered with the weak handle | 3098 // table. Generally external symbols are not registered with the weak handle |
| 3093 // callbacks unless they are upgraded to a symbol after being externalized. | 3099 // callbacks unless they are upgraded to a symbol after being externalized. |
| 3094 if (!str->IsSymbol()) { | 3100 if (!str->IsSymbol()) { |
| 3095 v8::String::ExternalStringResource* resource = | 3101 v8::String::ExternalStringResource* resource = |
| 3096 reinterpret_cast<v8::String::ExternalStringResource*>(parameter); | 3102 reinterpret_cast<v8::String::ExternalStringResource*>(parameter); |
| 3097 if (resource != NULL) { | 3103 if (resource != NULL) { |
| 3098 const int total_size = | 3104 const int total_size = |
| 3099 static_cast<int>(resource->length() * sizeof(*resource->data())); | 3105 static_cast<int>(resource->length() * sizeof(*resource->data())); |
| 3100 i::Counters::total_external_string_memory.Decrement(total_size); | 3106 DECREMENT_COUNTER(total_external_string_memory, total_size); |
| 3101 | 3107 |
| 3102 // The object will continue to live in the JavaScript heap until the | 3108 // The object will continue to live in the JavaScript heap until the |
| 3103 // handle is entirely cleaned out by the next GC. For example the | 3109 // handle is entirely cleaned out by the next GC. For example the |
| 3104 // destructor for the resource below could bring it back to life again. | 3110 // destructor for the resource below could bring it back to life again. |
| 3105 // Which is why we make sure to not have a dangling pointer here. | 3111 // Which is why we make sure to not have a dangling pointer here. |
| 3106 str->set_resource(NULL); | 3112 str->set_resource(NULL); |
| 3107 delete resource; | 3113 delete resource; |
| 3108 } | 3114 } |
| 3109 } | 3115 } |
| 3110 | 3116 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3121 | 3127 |
| 3122 // External symbols are deleted when they are pruned out of the symbol | 3128 // External symbols are deleted when they are pruned out of the symbol |
| 3123 // table. Generally external symbols are not registered with the weak handle | 3129 // table. Generally external symbols are not registered with the weak handle |
| 3124 // callbacks unless they are upgraded to a symbol after being externalized. | 3130 // callbacks unless they are upgraded to a symbol after being externalized. |
| 3125 if (!str->IsSymbol()) { | 3131 if (!str->IsSymbol()) { |
| 3126 v8::String::ExternalAsciiStringResource* resource = | 3132 v8::String::ExternalAsciiStringResource* resource = |
| 3127 reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter); | 3133 reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter); |
| 3128 if (resource != NULL) { | 3134 if (resource != NULL) { |
| 3129 const int total_size = | 3135 const int total_size = |
| 3130 static_cast<int>(resource->length() * sizeof(*resource->data())); | 3136 static_cast<int>(resource->length() * sizeof(*resource->data())); |
| 3131 i::Counters::total_external_string_memory.Decrement(total_size); | 3137 DECREMENT_COUNTER(total_external_string_memory, total_size); |
| 3132 | 3138 |
| 3133 // The object will continue to live in the JavaScript heap until the | 3139 // The object will continue to live in the JavaScript heap until the |
| 3134 // handle is entirely cleaned out by the next GC. For example the | 3140 // handle is entirely cleaned out by the next GC. For example the |
| 3135 // destructor for the resource below could bring it back to life again. | 3141 // destructor for the resource below could bring it back to life again. |
| 3136 // Which is why we make sure to not have a dangling pointer here. | 3142 // Which is why we make sure to not have a dangling pointer here. |
| 3137 str->set_resource(NULL); | 3143 str->set_resource(NULL); |
| 3138 delete resource; | 3144 delete resource; |
| 3139 } | 3145 } |
| 3140 } | 3146 } |
| 3141 | 3147 |
| 3142 // In any case we do not need this handle any longer. | 3148 // In any case we do not need this handle any longer. |
| 3143 obj.Dispose(); | 3149 obj.Dispose(); |
| 3144 } | 3150 } |
| 3145 | 3151 |
| 3146 | 3152 |
| 3147 Local<String> v8::String::NewExternal( | 3153 Local<String> v8::String::NewExternal( |
| 3148 v8::String::ExternalStringResource* resource) { | 3154 v8::String::ExternalStringResource* resource) { |
| 3149 EnsureInitialized("v8::String::NewExternal()"); | 3155 EnsureInitialized("v8::String::NewExternal()"); |
| 3150 LOG_API("String::NewExternal"); | 3156 LOG_API("String::NewExternal"); |
| 3151 ENTER_V8; | 3157 ENTER_V8; |
| 3152 const int total_size = | 3158 const int total_size = |
| 3153 static_cast<int>(resource->length() * sizeof(*resource->data())); | 3159 static_cast<int>(resource->length() * sizeof(*resource->data())); |
| 3154 i::Counters::total_external_string_memory.Increment(total_size); | 3160 INCREMENT_COUNTER(total_external_string_memory, total_size); |
| 3155 i::Handle<i::String> result = NewExternalStringHandle(resource); | 3161 i::Handle<i::String> result = NewExternalStringHandle(resource); |
| 3156 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result); | 3162 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result); |
| 3157 i::GlobalHandles::MakeWeak(handle.location(), | 3163 i::GlobalHandles::MakeWeak(handle.location(), |
| 3158 resource, | 3164 resource, |
| 3159 &DisposeExternalString); | 3165 &DisposeExternalString); |
| 3160 return Utils::ToLocal(result); | 3166 return Utils::ToLocal(result); |
| 3161 } | 3167 } |
| 3162 | 3168 |
| 3163 | 3169 |
| 3164 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { | 3170 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3180 } | 3186 } |
| 3181 | 3187 |
| 3182 | 3188 |
| 3183 Local<String> v8::String::NewExternal( | 3189 Local<String> v8::String::NewExternal( |
| 3184 v8::String::ExternalAsciiStringResource* resource) { | 3190 v8::String::ExternalAsciiStringResource* resource) { |
| 3185 EnsureInitialized("v8::String::NewExternal()"); | 3191 EnsureInitialized("v8::String::NewExternal()"); |
| 3186 LOG_API("String::NewExternal"); | 3192 LOG_API("String::NewExternal"); |
| 3187 ENTER_V8; | 3193 ENTER_V8; |
| 3188 const int total_size = | 3194 const int total_size = |
| 3189 static_cast<int>(resource->length() * sizeof(*resource->data())); | 3195 static_cast<int>(resource->length() * sizeof(*resource->data())); |
| 3190 i::Counters::total_external_string_memory.Increment(total_size); | 3196 INCREMENT_COUNTER(total_external_string_memory, total_size); |
| 3191 i::Handle<i::String> result = NewExternalAsciiStringHandle(resource); | 3197 i::Handle<i::String> result = NewExternalAsciiStringHandle(resource); |
| 3192 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result); | 3198 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result); |
| 3193 i::GlobalHandles::MakeWeak(handle.location(), | 3199 i::GlobalHandles::MakeWeak(handle.location(), |
| 3194 resource, | 3200 resource, |
| 3195 &DisposeExternalAsciiString); | 3201 &DisposeExternalAsciiString); |
| 3196 return Utils::ToLocal(result); | 3202 return Utils::ToLocal(result); |
| 3197 } | 3203 } |
| 3198 | 3204 |
| 3199 | 3205 |
| 3200 bool v8::String::MakeExternal( | 3206 bool v8::String::MakeExternal( |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3343 if (fits_into_int32_t) { | 3349 if (fits_into_int32_t) { |
| 3344 return Integer::New(static_cast<int32_t>(value)); | 3350 return Integer::New(static_cast<int32_t>(value)); |
| 3345 } | 3351 } |
| 3346 ENTER_V8; | 3352 ENTER_V8; |
| 3347 i::Handle<i::Object> result = i::Factory::NewNumber(value); | 3353 i::Handle<i::Object> result = i::Factory::NewNumber(value); |
| 3348 return Utils::IntegerToLocal(result); | 3354 return Utils::IntegerToLocal(result); |
| 3349 } | 3355 } |
| 3350 | 3356 |
| 3351 | 3357 |
| 3352 void V8::IgnoreOutOfMemoryException() { | 3358 void V8::IgnoreOutOfMemoryException() { |
| 3353 thread_local.set_ignore_out_of_memory(true); | 3359 v8_context()->handle_scope_implementer_.set_ignore_out_of_memory(true); |
| 3354 } | 3360 } |
| 3355 | 3361 |
| 3356 | 3362 |
| 3357 bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) { | 3363 bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) { |
| 3358 EnsureInitialized("v8::V8::AddMessageListener()"); | 3364 EnsureInitialized("v8::V8::AddMessageListener()"); |
| 3359 ON_BAILOUT("v8::V8::AddMessageListener()", return false); | 3365 ON_BAILOUT("v8::V8::AddMessageListener()", return false); |
| 3360 ENTER_V8; | 3366 ENTER_V8; |
| 3361 HandleScope scope; | 3367 HandleScope scope; |
| 3362 NeanderArray listeners(i::Factory::message_listeners()); | 3368 NeanderArray listeners(i::Factory::message_listeners()); |
| 3363 NeanderObject obj(2); | 3369 NeanderObject obj(2); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3829 | 3835 |
| 3830 bool Debug::EnableAgent(const char* name, int port) { | 3836 bool Debug::EnableAgent(const char* name, int port) { |
| 3831 return i::Debugger::StartAgent(name, port); | 3837 return i::Debugger::StartAgent(name, port); |
| 3832 } | 3838 } |
| 3833 #endif // ENABLE_DEBUGGER_SUPPORT | 3839 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3834 | 3840 |
| 3835 namespace internal { | 3841 namespace internal { |
| 3836 | 3842 |
| 3837 | 3843 |
| 3838 HandleScopeImplementer* HandleScopeImplementer::instance() { | 3844 HandleScopeImplementer* HandleScopeImplementer::instance() { |
| 3839 return &thread_local; | 3845 return &v8_context()->handle_scope_implementer_; |
| 3840 } | 3846 } |
| 3841 | 3847 |
| 3842 | 3848 |
| 3843 void HandleScopeImplementer::FreeThreadResources() { | 3849 void HandleScopeImplementer::FreeThreadResources() { |
| 3844 thread_local.Free(); | 3850 v8_context()->handle_scope_implementer_.Free(); |
| 3845 } | 3851 } |
| 3846 | 3852 |
| 3847 | 3853 |
| 3848 char* HandleScopeImplementer::ArchiveThread(char* storage) { | 3854 char* HandleScopeImplementer::ArchiveThread(char* storage) { |
| 3849 return thread_local.ArchiveThreadHelper(storage); | 3855 return v8_context()->handle_scope_implementer_.ArchiveThreadHelper(storage); |
| 3850 } | 3856 } |
| 3851 | 3857 |
| 3852 | 3858 |
| 3853 char* HandleScopeImplementer::ArchiveThreadHelper(char* storage) { | 3859 char* HandleScopeImplementer::ArchiveThreadHelper(char* storage) { |
| 3854 v8::ImplementationUtilities::HandleScopeData* current = | 3860 v8::ImplementationUtilities::HandleScopeData* current = |
| 3855 v8::ImplementationUtilities::CurrentHandleScope(); | 3861 v8::ImplementationUtilities::CurrentHandleScope(); |
| 3856 handle_scope_data_ = *current; | 3862 handle_scope_data_ = *current; |
| 3857 memcpy(storage, this, sizeof(*this)); | 3863 memcpy(storage, this, sizeof(*this)); |
| 3858 | 3864 |
| 3859 ResetAfterArchive(); | 3865 ResetAfterArchive(); |
| 3860 current->Initialize(); | 3866 current->Initialize(); |
| 3861 | 3867 |
| 3862 return storage + ArchiveSpacePerThread(); | 3868 return storage + ArchiveSpacePerThread(); |
| 3863 } | 3869 } |
| 3864 | 3870 |
| 3865 | 3871 |
| 3866 int HandleScopeImplementer::ArchiveSpacePerThread() { | 3872 int HandleScopeImplementer::ArchiveSpacePerThread() { |
| 3867 return sizeof(thread_local); | 3873 return sizeof(HandleScopeImplementer); |
| 3868 } | 3874 } |
| 3869 | 3875 |
| 3870 | 3876 |
| 3871 char* HandleScopeImplementer::RestoreThread(char* storage) { | 3877 char* HandleScopeImplementer::RestoreThread(char* storage) { |
| 3872 return thread_local.RestoreThreadHelper(storage); | 3878 return v8_context()->handle_scope_implementer_.RestoreThreadHelper(storage); |
| 3873 } | 3879 } |
| 3874 | 3880 |
| 3875 | 3881 |
| 3876 char* HandleScopeImplementer::RestoreThreadHelper(char* storage) { | 3882 char* HandleScopeImplementer::RestoreThreadHelper(char* storage) { |
| 3877 memcpy(this, storage, sizeof(*this)); | 3883 memcpy(this, storage, sizeof(*this)); |
| 3878 *v8::ImplementationUtilities::CurrentHandleScope() = handle_scope_data_; | 3884 *v8::ImplementationUtilities::CurrentHandleScope() = handle_scope_data_; |
| 3879 return storage + ArchiveSpacePerThread(); | 3885 return storage + ArchiveSpacePerThread(); |
| 3880 } | 3886 } |
| 3881 | 3887 |
| 3882 | 3888 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3895 if (!saved_contexts_.is_empty()) { | 3901 if (!saved_contexts_.is_empty()) { |
| 3896 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first()); | 3902 Object** start = reinterpret_cast<Object**>(&saved_contexts_.first()); |
| 3897 v->VisitPointers(start, start + saved_contexts_.length()); | 3903 v->VisitPointers(start, start + saved_contexts_.length()); |
| 3898 } | 3904 } |
| 3899 } | 3905 } |
| 3900 | 3906 |
| 3901 | 3907 |
| 3902 void HandleScopeImplementer::Iterate(ObjectVisitor* v) { | 3908 void HandleScopeImplementer::Iterate(ObjectVisitor* v) { |
| 3903 v8::ImplementationUtilities::HandleScopeData* current = | 3909 v8::ImplementationUtilities::HandleScopeData* current = |
| 3904 v8::ImplementationUtilities::CurrentHandleScope(); | 3910 v8::ImplementationUtilities::CurrentHandleScope(); |
| 3905 thread_local.handle_scope_data_ = *current; | 3911 HandleScopeImplementer& handle_scope_implementer = |
| 3906 thread_local.IterateThis(v); | 3912 v8_context()->handle_scope_implementer_; |
| 3913 handle_scope_implementer.handle_scope_data_ = *current; |
| 3914 handle_scope_implementer.IterateThis(v); |
| 3907 } | 3915 } |
| 3908 | 3916 |
| 3909 | 3917 |
| 3910 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { | 3918 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { |
| 3911 HandleScopeImplementer* thread_local = | 3919 HandleScopeImplementer* thread_local = |
| 3912 reinterpret_cast<HandleScopeImplementer*>(storage); | 3920 reinterpret_cast<HandleScopeImplementer*>(storage); |
| 3913 thread_local->IterateThis(v); | 3921 thread_local->IterateThis(v); |
| 3914 return storage + ArchiveSpacePerThread(); | 3922 return storage + ArchiveSpacePerThread(); |
| 3915 } | 3923 } |
| 3916 | 3924 |
| 3917 } } // namespace v8::internal | 3925 } } // namespace v8::internal |
| OLD | NEW |