OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 template <typename T> static inline T ToCData(v8::internal::Object* obj) { | 115 template <typename T> static inline T ToCData(v8::internal::Object* obj) { |
116 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); | 116 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); |
117 return reinterpret_cast<T>( | 117 return reinterpret_cast<T>( |
118 reinterpret_cast<intptr_t>(v8::internal::Proxy::cast(obj)->proxy())); | 118 reinterpret_cast<intptr_t>(v8::internal::Proxy::cast(obj)->proxy())); |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 template <typename T> | 122 template <typename T> |
123 static inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) { | 123 static inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) { |
124 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); | 124 STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); |
125 return v8::internal::Factory::NewProxy( | 125 return FACTORY->NewProxy( |
126 reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj))); | 126 reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj))); |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 class ApiFunction { | 130 class ApiFunction { |
131 public: | 131 public: |
132 explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { } | 132 explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { } |
133 v8::internal::Address address() { return addr_; } | 133 v8::internal::Address address() { return addr_; } |
134 private: | 134 private: |
135 v8::internal::Address addr_; | 135 v8::internal::Address addr_; |
(...skipping 14 matching lines...) Expand all Loading... |
150 RegisteredExtension* next_auto() { return next_auto_; } | 150 RegisteredExtension* next_auto() { return next_auto_; } |
151 ExtensionTraversalState state() { return state_; } | 151 ExtensionTraversalState state() { return state_; } |
152 void set_state(ExtensionTraversalState value) { state_ = value; } | 152 void set_state(ExtensionTraversalState value) { state_ = value; } |
153 static RegisteredExtension* first_extension() { return first_extension_; } | 153 static RegisteredExtension* first_extension() { return first_extension_; } |
154 private: | 154 private: |
155 Extension* extension_; | 155 Extension* extension_; |
156 RegisteredExtension* next_; | 156 RegisteredExtension* next_; |
157 RegisteredExtension* next_auto_; | 157 RegisteredExtension* next_auto_; |
158 ExtensionTraversalState state_; | 158 ExtensionTraversalState state_; |
159 static RegisteredExtension* first_extension_; | 159 static RegisteredExtension* first_extension_; |
160 static RegisteredExtension* first_auto_extension_; | |
161 }; | 160 }; |
162 | 161 |
163 | 162 |
164 class Utils { | 163 class Utils { |
165 public: | 164 public: |
166 static bool ReportApiFailure(const char* location, const char* message); | 165 static bool ReportApiFailure(const char* location, const char* message); |
167 | 166 |
168 static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj); | 167 static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj); |
169 static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj); | 168 static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj); |
170 | 169 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 MAKE_OPEN_HANDLE(Context, Context) | 313 MAKE_OPEN_HANDLE(Context, Context) |
315 MAKE_OPEN_HANDLE(External, Proxy) | 314 MAKE_OPEN_HANDLE(External, Proxy) |
316 MAKE_OPEN_HANDLE(StackTrace, JSArray) | 315 MAKE_OPEN_HANDLE(StackTrace, JSArray) |
317 MAKE_OPEN_HANDLE(StackFrame, JSObject) | 316 MAKE_OPEN_HANDLE(StackFrame, JSObject) |
318 | 317 |
319 #undef MAKE_OPEN_HANDLE | 318 #undef MAKE_OPEN_HANDLE |
320 | 319 |
321 | 320 |
322 namespace internal { | 321 namespace internal { |
323 | 322 |
| 323 // Tracks string usage to help make better decisions when |
| 324 // externalizing strings. |
| 325 // |
| 326 // Implementation note: internally this class only tracks fresh |
| 327 // strings and keeps a single use counter for them. |
| 328 class StringTracker { |
| 329 public: |
| 330 // Records that the given string's characters were copied to some |
| 331 // external buffer. If this happens often we should honor |
| 332 // externalization requests for the string. |
| 333 void RecordWrite(Handle<String> string) { |
| 334 Address address = reinterpret_cast<Address>(*string); |
| 335 Address top = isolate_->heap()->NewSpaceTop(); |
| 336 if (IsFreshString(address, top)) { |
| 337 IncrementUseCount(top); |
| 338 } |
| 339 } |
| 340 |
| 341 // Estimates freshness and use frequency of the given string based |
| 342 // on how close it is to the new space top and the recorded usage |
| 343 // history. |
| 344 inline bool IsFreshUnusedString(Handle<String> string) { |
| 345 Address address = reinterpret_cast<Address>(*string); |
| 346 Address top = isolate_->heap()->NewSpaceTop(); |
| 347 return IsFreshString(address, top) && IsUseCountLow(top); |
| 348 } |
| 349 |
| 350 private: |
| 351 StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { } |
| 352 |
| 353 static inline bool IsFreshString(Address string, Address top) { |
| 354 return top - kFreshnessLimit <= string && string <= top; |
| 355 } |
| 356 |
| 357 inline bool IsUseCountLow(Address top) { |
| 358 if (last_top_ != top) return true; |
| 359 return use_count_ < kUseLimit; |
| 360 } |
| 361 |
| 362 inline void IncrementUseCount(Address top) { |
| 363 if (last_top_ != top) { |
| 364 use_count_ = 0; |
| 365 last_top_ = top; |
| 366 } |
| 367 ++use_count_; |
| 368 } |
| 369 |
| 370 // Single use counter shared by all fresh strings. |
| 371 int use_count_; |
| 372 |
| 373 // Last new space top when the use count above was valid. |
| 374 Address last_top_; |
| 375 |
| 376 Isolate* isolate_; |
| 377 |
| 378 // How close to the new space top a fresh string has to be. |
| 379 static const int kFreshnessLimit = 1024; |
| 380 |
| 381 // The number of uses required to consider a string useful. |
| 382 static const int kUseLimit = 32; |
| 383 |
| 384 friend class Isolate; |
| 385 |
| 386 DISALLOW_COPY_AND_ASSIGN(StringTracker); |
| 387 }; |
| 388 |
| 389 |
324 // This class is here in order to be able to declare it a friend of | 390 // This class is here in order to be able to declare it a friend of |
325 // HandleScope. Moving these methods to be members of HandleScope would be | 391 // HandleScope. Moving these methods to be members of HandleScope would be |
326 // neat in some ways, but it would expose external implementation details in | 392 // neat in some ways, but it would expose internal implementation details in |
327 // our public header file, which is undesirable. | 393 // our public header file, which is undesirable. |
328 // | 394 // |
329 // There is a singleton instance of this class to hold the per-thread data. | 395 // An isolate has a single instance of this class to hold the current thread's |
330 // For multithreaded V8 programs this data is copied in and out of storage | 396 // data. In multithreaded V8 programs this data is copied in and out of storage |
331 // so that the currently executing thread always has its own copy of this | 397 // so that the currently executing thread always has its own copy of this |
332 // data. | 398 // data. |
333 class HandleScopeImplementer { | 399 ISOLATED_CLASS HandleScopeImplementer { |
334 public: | 400 public: |
335 | 401 |
336 HandleScopeImplementer() | 402 HandleScopeImplementer() |
337 : blocks_(0), | 403 : blocks_(0), |
338 entered_contexts_(0), | 404 entered_contexts_(0), |
339 saved_contexts_(0), | 405 saved_contexts_(0), |
340 spare_(NULL), | 406 spare_(NULL), |
341 ignore_out_of_memory_(false), | 407 ignore_out_of_memory_(false), |
342 call_depth_(0) { } | 408 call_depth_(0) { } |
343 | 409 |
344 static HandleScopeImplementer* instance(); | |
345 | |
346 // Threading support for handle data. | 410 // Threading support for handle data. |
347 static int ArchiveSpacePerThread(); | 411 static int ArchiveSpacePerThread(); |
348 static char* RestoreThread(char* from); | 412 char* RestoreThread(char* from); |
349 static char* ArchiveThread(char* to); | 413 char* ArchiveThread(char* to); |
350 static void FreeThreadResources(); | 414 void FreeThreadResources(); |
351 | 415 |
352 // Garbage collection support. | 416 // Garbage collection support. |
353 static void Iterate(v8::internal::ObjectVisitor* v); | 417 void Iterate(v8::internal::ObjectVisitor* v); |
354 static char* Iterate(v8::internal::ObjectVisitor* v, char* data); | 418 static char* Iterate(v8::internal::ObjectVisitor* v, char* data); |
355 | 419 |
356 | 420 |
357 inline internal::Object** GetSpareOrNewBlock(); | 421 inline internal::Object** GetSpareOrNewBlock(); |
358 inline void DeleteExtensions(internal::Object** prev_limit); | 422 inline void DeleteExtensions(internal::Object** prev_limit); |
359 | 423 |
360 inline void IncrementCallDepth() {call_depth_++;} | 424 inline void IncrementCallDepth() {call_depth_++;} |
361 inline void DecrementCallDepth() {call_depth_--;} | 425 inline void DecrementCallDepth() {call_depth_--;} |
362 inline bool CallDepthIsZero() { return call_depth_ == 0; } | 426 inline bool CallDepthIsZero() { return call_depth_ == 0; } |
363 | 427 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 stress_type_ = stress_type; | 563 stress_type_ = stress_type; |
500 } | 564 } |
501 | 565 |
502 private: | 566 private: |
503 static v8::Testing::StressType stress_type_; | 567 static v8::Testing::StressType stress_type_; |
504 }; | 568 }; |
505 | 569 |
506 } } // namespace v8::internal | 570 } } // namespace v8::internal |
507 | 571 |
508 #endif // V8_API_H_ | 572 #endif // V8_API_H_ |
OLD | NEW |