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 |