| 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 |