Index: src/heap-inl.h |
=================================================================== |
--- src/heap-inl.h (revision 7267) |
+++ src/heap-inl.h (working copy) |
@@ -30,11 +30,20 @@ |
#include "heap.h" |
#include "objects.h" |
+#include "isolate.h" |
#include "v8-counters.h" |
namespace v8 { |
namespace internal { |
+void PromotionQueue::insert(HeapObject* target, int size) { |
+ *(--rear_) = reinterpret_cast<intptr_t>(target); |
+ *(--rear_) = size; |
+ // Assert no overflow into live objects. |
+ ASSERT(reinterpret_cast<Address>(rear_) >= HEAP->new_space()->top()); |
+} |
+ |
+ |
int Heap::MaxObjectSizeInPagedSpace() { |
return Page::kMaxHeapObjectSize; |
} |
@@ -146,8 +155,8 @@ |
Heap::allocation_timeout_-- <= 0) { |
return Failure::RetryAfterGC(space); |
} |
- Counters::objs_since_last_full.Increment(); |
- Counters::objs_since_last_young.Increment(); |
+ isolate_->counters()->objs_since_last_full()->Increment(); |
+ isolate_->counters()->objs_since_last_young()->Increment(); |
#endif |
MaybeObject* result; |
if (NEW_SPACE == space) { |
@@ -214,8 +223,8 @@ |
MaybeObject* Heap::AllocateRawMap() { |
#ifdef DEBUG |
- Counters::objs_since_last_full.Increment(); |
- Counters::objs_since_last_young.Increment(); |
+ isolate_->counters()->objs_since_last_full()->Increment(); |
+ isolate_->counters()->objs_since_last_young()->Increment(); |
#endif |
MaybeObject* result = map_space_->AllocateRaw(Map::kSize); |
if (result->IsFailure()) old_gen_exhausted_ = true; |
@@ -232,8 +241,8 @@ |
MaybeObject* Heap::AllocateRawCell() { |
#ifdef DEBUG |
- Counters::objs_since_last_full.Increment(); |
- Counters::objs_since_last_young.Increment(); |
+ isolate_->counters()->objs_since_last_full()->Increment(); |
+ isolate_->counters()->objs_since_last_young()->Increment(); |
#endif |
MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize); |
if (result->IsFailure()) old_gen_exhausted_ = true; |
@@ -341,7 +350,7 @@ |
remaining--) { |
Memory::Object_at(dst) = Memory::Object_at(src); |
- if (Heap::InNewSpace(Memory::Object_at(dst))) { |
+ if (InNewSpace(Memory::Object_at(dst))) { |
marks |= page->GetRegionMaskForAddress(dst); |
} |
@@ -387,8 +396,13 @@ |
} |
+void Heap::ScavengePointer(HeapObject** p) { |
+ ScavengeObject(p, *p); |
+} |
+ |
+ |
void Heap::ScavengeObject(HeapObject** p, HeapObject* object) { |
- ASSERT(InFromSpace(object)); |
+ ASSERT(HEAP->InFromSpace(object)); |
// We use the first word (where the map pointer usually is) of a heap |
// object to record the forwarding pointer. A forwarding pointer can |
@@ -461,10 +475,15 @@ |
roots_[kLastScriptIdRootIndex] = last_script_id; |
} |
+Isolate* Heap::isolate() { |
+ return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) - |
+ reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4); |
+} |
+ |
#ifdef DEBUG |
#define GC_GREEDY_CHECK() \ |
- if (FLAG_gc_greedy) v8::internal::Heap::GarbageCollectionGreedyCheck() |
+ if (FLAG_gc_greedy) HEAP->GarbageCollectionGreedyCheck() |
#else |
#define GC_GREEDY_CHECK() { } |
#endif |
@@ -477,7 +496,7 @@ |
// Warning: Do not use the identifiers __object__, __maybe_object__ or |
// __scope__ in a call to this macro. |
-#define CALL_AND_RETRY(FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ |
+#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)\ |
do { \ |
GC_GREEDY_CHECK(); \ |
MaybeObject* __maybe_object__ = FUNCTION_CALL; \ |
@@ -487,16 +506,16 @@ |
v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\ |
} \ |
if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ |
- Heap::CollectGarbage( \ |
- Failure::cast(__maybe_object__)->allocation_space()); \ |
+ ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ |
+ allocation_space()); \ |
__maybe_object__ = FUNCTION_CALL; \ |
if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ |
if (__maybe_object__->IsOutOfMemory()) { \ |
v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\ |
} \ |
if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ |
- Counters::gc_last_resort_from_handles.Increment(); \ |
- Heap::CollectAllAvailableGarbage(); \ |
+ ISOLATE->counters()->gc_last_resort_from_handles()->Increment(); \ |
+ ISOLATE->heap()->CollectAllAvailableGarbage(); \ |
{ \ |
AlwaysAllocateScope __scope__; \ |
__maybe_object__ = FUNCTION_CALL; \ |
@@ -511,14 +530,17 @@ |
} while (false) |
-#define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \ |
- CALL_AND_RETRY(FUNCTION_CALL, \ |
- return Handle<TYPE>(TYPE::cast(__object__)), \ |
+// TODO(isolates): cache isolate: either accept as a parameter or |
+// set to some known symbol (__CUR_ISOLATE__?) |
+#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ |
+ CALL_AND_RETRY(ISOLATE, \ |
+ FUNCTION_CALL, \ |
+ return Handle<TYPE>(TYPE::cast(__object__), ISOLATE), \ |
return Handle<TYPE>()) |
-#define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL) \ |
- CALL_AND_RETRY(FUNCTION_CALL, return, return) |
+#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ |
+ CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) |
#ifdef DEBUG |
@@ -534,7 +556,7 @@ |
void ExternalStringTable::AddString(String* string) { |
ASSERT(string->IsExternalString()); |
- if (Heap::InNewSpace(string)) { |
+ if (heap_->InNewSpace(string)) { |
new_space_strings_.Add(string); |
} else { |
old_space_strings_.Add(string); |
@@ -559,12 +581,12 @@ |
void ExternalStringTable::Verify() { |
#ifdef DEBUG |
for (int i = 0; i < new_space_strings_.length(); ++i) { |
- ASSERT(Heap::InNewSpace(new_space_strings_[i])); |
- ASSERT(new_space_strings_[i] != Heap::raw_unchecked_null_value()); |
+ ASSERT(heap_->InNewSpace(new_space_strings_[i])); |
+ ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_null_value()); |
} |
for (int i = 0; i < old_space_strings_.length(); ++i) { |
- ASSERT(!Heap::InNewSpace(old_space_strings_[i])); |
- ASSERT(old_space_strings_[i] != Heap::raw_unchecked_null_value()); |
+ ASSERT(!heap_->InNewSpace(old_space_strings_[i])); |
+ ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_null_value()); |
} |
#endif |
} |
@@ -572,7 +594,7 @@ |
void ExternalStringTable::AddOldString(String* string) { |
ASSERT(string->IsExternalString()); |
- ASSERT(!Heap::InNewSpace(string)); |
+ ASSERT(!heap_->InNewSpace(string)); |
old_space_strings_.Add(string); |
} |
@@ -582,6 +604,100 @@ |
Verify(); |
} |
+ |
+void Heap::ClearInstanceofCache() { |
+ set_instanceof_cache_function(the_hole_value()); |
+} |
+ |
+ |
+Object* Heap::ToBoolean(bool condition) { |
+ return condition ? true_value() : false_value(); |
+} |
+ |
+ |
+void Heap::CompletelyClearInstanceofCache() { |
+ set_instanceof_cache_map(the_hole_value()); |
+ set_instanceof_cache_function(the_hole_value()); |
+} |
+ |
+ |
+MaybeObject* TranscendentalCache::Get(Type type, double input) { |
+ SubCache* cache = caches_[type]; |
+ if (cache == NULL) { |
+ caches_[type] = cache = new SubCache(type); |
+ } |
+ return cache->Get(input); |
+} |
+ |
+ |
+Address TranscendentalCache::cache_array_address() { |
+ return reinterpret_cast<Address>(caches_); |
+} |
+ |
+ |
+double TranscendentalCache::SubCache::Calculate(double input) { |
+ switch (type_) { |
+ case ACOS: |
+ return acos(input); |
+ case ASIN: |
+ return asin(input); |
+ case ATAN: |
+ return atan(input); |
+ case COS: |
+ return cos(input); |
+ case EXP: |
+ return exp(input); |
+ case LOG: |
+ return log(input); |
+ case SIN: |
+ return sin(input); |
+ case TAN: |
+ return tan(input); |
+ default: |
+ return 0.0; // Never happens. |
+ } |
+} |
+ |
+ |
+MaybeObject* TranscendentalCache::SubCache::Get(double input) { |
+ Converter c; |
+ c.dbl = input; |
+ int hash = Hash(c); |
+ Element e = elements_[hash]; |
+ if (e.in[0] == c.integers[0] && |
+ e.in[1] == c.integers[1]) { |
+ ASSERT(e.output != NULL); |
+ isolate_->counters()->transcendental_cache_hit()->Increment(); |
+ return e.output; |
+ } |
+ double answer = Calculate(input); |
+ isolate_->counters()->transcendental_cache_miss()->Increment(); |
+ Object* heap_number; |
+ { MaybeObject* maybe_heap_number = |
+ isolate_->heap()->AllocateHeapNumber(answer); |
+ if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number; |
+ } |
+ elements_[hash].in[0] = c.integers[0]; |
+ elements_[hash].in[1] = c.integers[1]; |
+ elements_[hash].output = heap_number; |
+ return heap_number; |
+} |
+ |
+ |
+Heap* _inline_get_heap_() { |
+ return HEAP; |
+} |
+ |
+ |
+void MarkCompactCollector::SetMark(HeapObject* obj) { |
+ tracer_->increment_marked_count(); |
+#ifdef DEBUG |
+ UpdateLiveObjectCount(obj); |
+#endif |
+ obj->SetMark(); |
+} |
+ |
+ |
} } // namespace v8::internal |
#endif // V8_HEAP_INL_H_ |