Version 3.2.4.
Added isolates which allows several V8 instances in the same process. This is controlled through the new Isolate class in the API.
Implemented more of EcmaScript 5 strict mode.
Reduced the time it takes to make detailed heap snapshot.
Added a number of commands to the ARM simulator and enhanced the ARM disassembler.
git-svn-id: http://v8.googlecode.com/svn/trunk@7322 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/frames.cc b/src/frames.cc
index 7dae462..30d0456 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -35,13 +35,10 @@
#include "safepoint-table.h"
#include "scopeinfo.h"
#include "string-stream.h"
-#include "top.h"
namespace v8 {
namespace internal {
-PcToCodeCache::PcToCodeCacheEntry
- PcToCodeCache::cache_[PcToCodeCache::kPcToCodeCacheSize];
int SafeStackFrameIterator::active_count_ = 0;
@@ -77,7 +74,8 @@
#define INITIALIZE_SINGLETON(type, field) field##_(this),
StackFrameIterator::StackFrameIterator()
: STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
- frame_(NULL), handler_(NULL), thread_(Top::GetCurrentThread()),
+ frame_(NULL), handler_(NULL),
+ thread_(Isolate::Current()->thread_local_top()),
fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
Reset();
}
@@ -87,10 +85,11 @@
fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
Reset();
}
-StackFrameIterator::StackFrameIterator(bool use_top, Address fp, Address sp)
+StackFrameIterator::StackFrameIterator(Isolate* isolate,
+ bool use_top, Address fp, Address sp)
: STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
frame_(NULL), handler_(NULL),
- thread_(use_top ? Top::GetCurrentThread() : NULL),
+ thread_(use_top ? isolate->thread_local_top() : NULL),
fp_(use_top ? NULL : fp), sp_(sp),
advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
&StackFrameIterator::AdvanceWithoutHandler) {
@@ -138,8 +137,10 @@
StackFrame::State state;
StackFrame::Type type;
if (thread_ != NULL) {
- type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state);
- handler_ = StackHandler::FromAddress(Top::handler(thread_));
+ type = ExitFrame::GetStateForFramePointer(
+ Isolate::c_entry_fp(thread_), &state);
+ handler_ = StackHandler::FromAddress(
+ Isolate::handler(thread_));
} else {
ASSERT(fp_ != NULL);
state.fp = fp_;
@@ -221,22 +222,25 @@
SafeStackFrameIterator::SafeStackFrameIterator(
+ Isolate* isolate,
Address fp, Address sp, Address low_bound, Address high_bound) :
maintainer_(),
stack_validator_(low_bound, high_bound),
- is_valid_top_(IsValidTop(low_bound, high_bound)),
+ is_valid_top_(IsValidTop(isolate, low_bound, high_bound)),
is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
is_working_iterator_(is_valid_top_ || is_valid_fp_),
iteration_done_(!is_working_iterator_),
- iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
+ iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
}
-bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) {
- Address fp = Top::c_entry_fp(Top::GetCurrentThread());
+bool SafeStackFrameIterator::IsValidTop(Isolate* isolate,
+ Address low_bound, Address high_bound) {
+ ThreadLocalTop* top = isolate->thread_local_top();
+ Address fp = Isolate::c_entry_fp(top);
ExitFrameValidator validator(low_bound, high_bound);
if (!validator.IsValidFP(fp)) return false;
- return Top::handler(Top::GetCurrentThread()) != NULL;
+ return Isolate::handler(top) != NULL;
}
@@ -312,8 +316,9 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
+ Isolate* isolate,
Address fp, Address sp, Address low_bound, Address high_bound) :
- SafeJavaScriptFrameIterator(fp, sp, low_bound, high_bound) {
+ SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) {
if (!done() && !frame()->is_java_script()) Advance();
}
@@ -331,7 +336,9 @@
Code* StackFrame::GetSafepointData(Address pc,
SafepointEntry* safepoint_entry,
unsigned* stack_slots) {
- PcToCodeCache::PcToCodeCacheEntry* entry = PcToCodeCache::GetCacheEntry(pc);
+ Isolate* isolate = Isolate::Current();
+ PcToCodeCache::PcToCodeCacheEntry* entry =
+ isolate->pc_to_code_cache()->GetCacheEntry(pc);
SafepointEntry cached_safepoint_entry = entry->safepoint_entry;
if (!entry->safepoint_entry.is_valid()) {
entry->safepoint_entry = entry->code->GetSafepointEntry(pc);
@@ -386,7 +393,8 @@
// into the heap to determine the state. This is safe as long
// as nobody tries to GC...
if (SafeStackFrameIterator::is_active()) return JAVA_SCRIPT;
- Code::Kind kind = GetContainingCode(*(state->pc_address))->kind();
+ Code::Kind kind = GetContainingCode(Isolate::Current(),
+ *(state->pc_address))->kind();
ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
}
@@ -402,7 +410,7 @@
Code* EntryFrame::unchecked_code() const {
- return Heap::raw_unchecked_js_entry_code();
+ return HEAP->raw_unchecked_js_entry_code();
}
@@ -425,7 +433,7 @@
Code* EntryConstructFrame::unchecked_code() const {
- return Heap::raw_unchecked_js_construct_entry_code();
+ return HEAP->raw_unchecked_js_construct_entry_code();
}
@@ -457,7 +465,7 @@
void ExitFrame::Iterate(ObjectVisitor* v) const {
// The arguments are traversed as part of the expression stack of
// the calling frame.
- IteratePc(v, pc_address(), code());
+ IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
v->VisitPointer(&code_slot());
}
@@ -632,8 +640,8 @@
Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments;
- if (Heap::gc_state() != Heap::NOT_IN_GC ||
- SafeStackFrameIterator::is_active()) {
+ if (SafeStackFrameIterator::is_active() ||
+ HEAP->gc_state() != Heap::NOT_IN_GC) {
// If the we are currently iterating the safe stack the
// arguments for frames are traversed as if they were
// expression stack elements of the calling frame. The reason for
@@ -662,7 +670,7 @@
void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
ASSERT(functions->length() == 0);
- Code* code_pointer = code();
+ Code* code_pointer = LookupCode(Isolate::Current());
int offset = static_cast<int>(pc() - code_pointer->address());
FrameSummary summary(receiver(),
JSFunction::cast(function()),
@@ -781,7 +789,7 @@
// back to a slow search in this case to find the original optimized
// code object.
if (!code->contains(pc())) {
- code = PcToCodeCache::GcSafeFindCodeForPc(pc());
+ code = Isolate::Current()->pc_to_code_cache()->GcSafeFindCodeForPc(pc());
}
ASSERT(code != NULL);
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
@@ -842,7 +850,8 @@
Code* ArgumentsAdaptorFrame::unchecked_code() const {
- return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline);
+ return Isolate::Current()->builtins()->builtin(
+ Builtins::ArgumentsAdaptorTrampoline);
}
@@ -1036,14 +1045,14 @@
ASSERT(!it.done());
StackHandler* handler = it.handler();
ASSERT(handler->is_entry());
- handler->Iterate(v, code());
+ handler->Iterate(v, LookupCode(Isolate::Current()));
#ifdef DEBUG
// Make sure that the entry frame does not contain more than one
// stack handler.
it.Advance();
ASSERT(it.done());
#endif
- IteratePc(v, pc_address(), code());
+ IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
}
@@ -1060,7 +1069,7 @@
v->VisitPointers(base, reinterpret_cast<Object**>(address));
base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
// Traverse the pointers in the handler itself.
- handler->Iterate(v, code());
+ handler->Iterate(v, LookupCode(Isolate::Current()));
}
v->VisitPointers(base, limit);
}
@@ -1068,7 +1077,7 @@
void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
IterateExpressions(v);
- IteratePc(v, pc_address(), code());
+ IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
IterateArguments(v);
}
@@ -1087,7 +1096,7 @@
// Internal frames only have object pointers on the expression stack
// as they never have any arguments.
IterateExpressions(v);
- IteratePc(v, pc_address(), code());
+ IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
}
@@ -1117,14 +1126,15 @@
Code* PcToCodeCache::GcSafeFindCodeForPc(Address pc) {
+ Heap* heap = isolate_->heap();
// Check if the pc points into a large object chunk.
- LargeObjectChunk* chunk = Heap::lo_space()->FindChunkContainingPc(pc);
+ LargeObjectChunk* chunk = heap->lo_space()->FindChunkContainingPc(pc);
if (chunk != NULL) return GcSafeCastToCode(chunk->GetObject(), pc);
// Iterate through the 8K page until we reach the end or find an
// object starting after the pc.
Page* page = Page::FromAddress(pc);
- HeapObjectIterator iterator(page, Heap::GcSafeSizeOfOldObjectFunction());
+ HeapObjectIterator iterator(page, heap->GcSafeSizeOfOldObjectFunction());
HeapObject* previous = NULL;
while (true) {
HeapObject* next = iterator.next();
@@ -1137,14 +1147,14 @@
PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
- Counters::pc_to_code.Increment();
+ COUNTERS->pc_to_code()->Increment();
ASSERT(IsPowerOf2(kPcToCodeCacheSize));
uint32_t hash = ComputeIntegerHash(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc)));
uint32_t index = hash & (kPcToCodeCacheSize - 1);
PcToCodeCacheEntry* entry = cache(index);
if (entry->pc == pc) {
- Counters::pc_to_code_cached.Increment();
+ COUNTERS->pc_to_code_cached()->Increment();
ASSERT(entry->code == GcSafeFindCodeForPc(pc));
} else {
// Because this code may be interrupted by a profiling signal that
@@ -1171,11 +1181,8 @@
}
-int JSCallerSavedCode(int n) {
- static int reg_code[kNumJSCallerSaved];
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
+struct JSCallerSavedCodeData {
+ JSCallerSavedCodeData() {
int i = 0;
for (int r = 0; r < kNumRegs; r++)
if ((kJSCallerSaved & (1 << r)) != 0)
@@ -1183,8 +1190,16 @@
ASSERT(i == kNumJSCallerSaved);
}
+ int reg_code[kNumJSCallerSaved];
+};
+
+
+static const JSCallerSavedCodeData kCallerSavedCodeData;
+
+
+int JSCallerSavedCode(int n) {
ASSERT(0 <= n && n < kNumJSCallerSaved);
- return reg_code[n];
+ return kCallerSavedCodeData.reg_code[n];
}