// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
// The default fatal error handler is called and execution is stopped.
-void i::V8::FatalProcessOutOfMemory(const char* location) {
+static void ExecuteFatalProcessOutOfMemory(const char* location,
+ i::HeapStats* heap_stats) {
i::V8::SetFatalError();
FatalErrorCallback callback = GetFatalErrorHandler();
{
}
+void i::V8::FatalProcessOutOfMemory(const char* location) {
+ i::HeapStats heap_stats;
+ i::Heap::RecordStats(&heap_stats);
+ ExecuteFatalProcessOutOfMemory(location, &heap_stats);
+}
+
+
void V8::SetFatalErrorHandler(FatalErrorCallback that) {
exception_behavior = that;
}
GlobalHandles::Node* GlobalHandles::first_free_ = NULL;
GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL;
+void GlobalHandles::RecordStats(HeapStats* stats) {
+ stats->global_handle_count = 0;
+ stats->weak_global_handle_count = 0;
+ stats->pending_global_handle_count = 0;
+ stats->near_death_global_handle_count = 0;
+ stats->destroyed_global_handle_count = 0;
+ for (Node* current = head_; current != NULL; current = current->next()) {
+ stats->global_handle_count++;
+ if (current->state_ == Node::WEAK) {
+ stats->weak_global_handle_count++;
+ } else if (current->state_ == Node::PENDING) {
+ stats->pending_global_handle_count++;
+ } else if (current->state_ == Node::NEAR_DEATH) {
+ stats->near_death_global_handle_count++;
+ } else if (current->state_ == Node::DESTROYED) {
+ stats->destroyed_global_handle_count++;
+ }
+ }
+}
+
#ifdef DEBUG
void GlobalHandles::PrintStats() {
// Returns the current number of weak handles.
static int NumberOfWeakHandles() { return number_of_weak_handles_; }
+ static void RecordStats(HeapStats* stats);
+
// Returns the current number of weak handles to global objects.
// These handles are also included in NumberOfWeakHandles().
static int NumberOfGlobalObjectWeakHandles() {
}
+void Heap::RecordStats(HeapStats* stats) {
+ stats->new_space_size = new_space_.Size();
+ stats->new_space_capacity = new_space_.Capacity();
+ stats->old_pointer_space_size = old_pointer_space_->Size();
+ stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
+ stats->old_data_space_size = old_data_space_->Size();
+ stats->old_data_space_capacity = old_data_space_->Capacity();
+ stats->code_space_size = code_space_->Size();
+ stats->code_space_capacity = code_space_->Capacity();
+ stats->map_space_size = map_space_->Size();
+ stats->map_space_capacity = map_space_->Capacity();
+ stats->cell_space_size = cell_space_->Size();
+ stats->cell_space_capacity = cell_space_->Capacity();
+ stats->lo_space_size = lo_space_->Size();
+ GlobalHandles::RecordStats(stats);
+}
+
+
int Heap::PromotedSpaceSize() {
return old_pointer_space_->Size()
+ old_data_space_->Size()
// Forward declaration of the GCTracer class.
class GCTracer;
+class HeapStats;
// The all static Heap captures the interface to the global object heap.
static RootListIndex RootIndexForExternalArrayType(
ExternalArrayType array_type);
+ static void RecordStats(HeapStats* stats);
+
private:
static int reserved_semispace_size_;
static int max_semispace_size_;
};
+struct HeapStats {
+ int new_space_size;
+ int new_space_capacity;
+ int old_pointer_space_size;
+ int old_pointer_space_capacity;
+ int old_data_space_size;
+ int old_data_space_capacity;
+ int code_space_size;
+ int code_space_capacity;
+ int map_space_size;
+ int map_space_capacity;
+ int cell_space_size;
+ int cell_space_capacity;
+ int lo_space_size;
+ int global_handle_count;
+ int weak_global_handle_count;
+ int pending_global_handle_count;
+ int near_death_global_handle_count;
+ int destroyed_global_handle_count;
+};
+
+
class AlwaysAllocateScope {
public:
AlwaysAllocateScope() {