Commit c093e945 authored by iposva@chromium.org's avatar iposva@chromium.org

- Pass the knowledge whether the old GC is compacting to the GC prologue and...

- Pass the knowledge whether the old GC is compacting to the GC prologue and epilogue. This allows us to skip frame cooking and uncooking when doing a mark-sweep GC.
- Add the ability for the code to refer to its code object by adding a handle to the code object in the MacroAssembler.

Review URL: http://codereview.chromium.org/27133

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1368 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 548a8bc2
......@@ -387,8 +387,8 @@ Object* Accessors::FunctionGetArguments(Object* object, void*) {
if (frame->function() != *function) continue;
// If there is an arguments variable in the stack, we return that.
int index = ScopeInfo<>::StackSlotIndex(frame->FindCode(),
Heap::arguments_symbol());
int index = ScopeInfo<>::StackSlotIndex(frame->code(),
Heap::arguments_symbol());
if (index >= 0) return frame->GetExpression(index);
// If there isn't an arguments variable in the stack, we need to
......
......@@ -688,7 +688,7 @@ void Builtins::Setup(bool create_heap_objects) {
// During startup it's OK to always allocate and defer GC to later.
// This simplifies things because we don't need to retry.
AlwaysAllocateScope __scope__;
code = Heap::CreateCode(desc, NULL, flags, NULL);
code = Heap::CreateCode(desc, NULL, flags, masm.CodeObject());
if (code->IsFailure()) {
v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
}
......
......@@ -59,7 +59,7 @@ Handle<Code> CodeStub::GetCode() {
// Copy the generated code into a heap object, and store the major key.
Code::Flags flags = Code::ComputeFlags(Code::STUB);
Handle<Code> code = Factory::NewCode(desc, NULL, flags);
Handle<Code> code = Factory::NewCode(desc, NULL, flags, masm.CodeObject());
code->set_major_key(MajorKey());
// Add unresolved entries in the code to the fixup list.
......
......@@ -130,7 +130,10 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* flit,
cgen.masm()->GetCode(&desc);
ScopeInfo<> sinfo(flit->scope());
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = Factory::NewCode(desc, &sinfo, flags);
Handle<Code> code = Factory::NewCode(desc,
&sinfo,
flags,
cgen.masm()->CodeObject());
// Add unresolved entries in the code to the fixup list.
Bootstrapper::AddFixup(*code, cgen.masm());
......
......@@ -1266,7 +1266,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
Handle<Code> original_code(debug_info->original_code());
#ifdef DEBUG
// Get the code which is actually executing.
Handle<Code> frame_code(frame->FindCode());
Handle<Code> frame_code(frame->code());
ASSERT(frame_code.is_identical_to(code));
#endif
......
......@@ -487,13 +487,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
Code::Flags flags, Handle<Object> self_ref) {
CALL_HEAP_FUNCTION(Heap::CreateCode(
desc, sinfo, flags, reinterpret_cast<Code**>(self_ref.location())), Code);
}
Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
Code::Flags flags) {
CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags, NULL), Code);
CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags, self_ref), Code);
}
......
......@@ -206,9 +206,6 @@ class Factory : public AllStatic {
static Handle<Code> NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
Code::Flags flags, Handle<Object> self_reference);
static Handle<Code> NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
Code::Flags flags);
static Handle<Code> CopyCode(Handle<Code> code);
static Handle<Object> ToObject(Handle<Object> object,
......
......@@ -114,10 +114,4 @@ Address InternalFrame::GetCallerStackPointer() const {
}
Code* JavaScriptFrame::FindCode() const {
JSFunction* function = JSFunction::cast(this->function());
return function->shared()->code();
}
} } // namespace v8::internal
......@@ -112,10 +112,4 @@ Address InternalFrame::GetCallerStackPointer() const {
}
Code* JavaScriptFrame::FindCode() const {
JSFunction* function = JSFunction::cast(this->function());
return function->shared()->code();
}
} } // namespace v8::internal
......@@ -28,6 +28,7 @@
#include "v8.h"
#include "frames-inl.h"
#include "mark-compact.h"
#include "scopeinfo.h"
#include "string-stream.h"
#include "top.h"
......@@ -162,12 +163,14 @@ void JavaScriptFrameIterator::Reset() {
void StackHandler::Cook(Code* code) {
ASSERT(MarkCompactCollector::IsCompacting());
ASSERT(code->contains(pc()));
set_pc(AddressFrom<Address>(pc() - code->instruction_start()));
}
void StackHandler::Uncook(Code* code) {
ASSERT(MarkCompactCollector::IsCompacting());
set_pc(code->instruction_start() + OffsetFrom(pc()));
ASSERT(code->contains(pc()));
}
......@@ -183,6 +186,9 @@ bool StackFrame::HasHandler() const {
void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
// Only cooking frames when the collector is compacting and thus moving code
// around.
ASSERT(MarkCompactCollector::IsCompacting());
ASSERT(!thread->stack_is_cooked());
for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
it.frame()->Cook();
......@@ -192,6 +198,9 @@ void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {
// Only uncooking frames when the collector is compacting and thus moving code
// around.
ASSERT(MarkCompactCollector::IsCompacting());
ASSERT(thread->stack_is_cooked());
for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
it.frame()->Uncook();
......@@ -201,7 +210,7 @@ void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {
void StackFrame::Cook() {
Code* code = FindCode();
Code* code = this->code();
for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
it.handler()->Cook(code);
}
......@@ -211,7 +220,7 @@ void StackFrame::Cook() {
void StackFrame::Uncook() {
Code* code = FindCode();
Code* code = this->code();
for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
it.handler()->Uncook(code);
}
......@@ -220,7 +229,7 @@ void StackFrame::Uncook() {
}
Code* EntryFrame::FindCode() const {
Code* EntryFrame::code() const {
return Heap::js_entry_code();
}
......@@ -232,12 +241,12 @@ StackFrame::Type EntryFrame::GetCallerState(State* state) const {
}
Code* EntryConstructFrame::FindCode() const {
Code* EntryConstructFrame::code() const {
return Heap::js_construct_entry_code();
}
Code* ExitFrame::FindCode() const {
Code* ExitFrame::code() const {
return Heap::c_entry_code();
}
......@@ -257,7 +266,7 @@ Address ExitFrame::GetCallerStackPointer() const {
}
Code* ExitDebugFrame::FindCode() const {
Code* ExitDebugFrame::code() const {
return Heap::c_entry_debug_break_code();
}
......@@ -320,20 +329,20 @@ bool JavaScriptFrame::IsConstructor() const {
}
Code* ArgumentsAdaptorFrame::FindCode() const {
Code* JavaScriptFrame::code() const {
JSFunction* function = JSFunction::cast(this->function());
return function->shared()->code();
}
Code* ArgumentsAdaptorFrame::code() const {
return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline);
}
Code* InternalFrame::FindCode() const {
Code* InternalFrame::code() const {
const int offset = InternalFrameConstants::kCodeOffset;
Object* code = Memory::Object_at(fp() + offset);
if (code == NULL) {
// The code object isn't set; find it and set it.
code = Heap::FindCodeObject(pc());
ASSERT(!code->IsFailure());
Memory::Object_at(fp() + offset) = code;
}
ASSERT(code != NULL);
return Code::cast(code);
}
......
......@@ -148,7 +148,7 @@ class StackFrame BASE_EMBEDDED {
virtual Type type() const = 0;
// Get the code associated with this frame.
virtual Code* FindCode() const = 0;
virtual Code* code() const = 0;
// Garbage collection support.
static void CookFramesForThread(ThreadLocalTop* thread);
......@@ -209,7 +209,7 @@ class EntryFrame: public StackFrame {
public:
virtual Type type() const { return ENTRY; }
virtual Code* FindCode() const;
virtual Code* code() const;
// Garbage collection support.
virtual void Iterate(ObjectVisitor* v) const;
......@@ -238,7 +238,7 @@ class EntryConstructFrame: public EntryFrame {
public:
virtual Type type() const { return ENTRY_CONSTRUCT; }
virtual Code* FindCode() const;
virtual Code* code() const;
static EntryConstructFrame* cast(StackFrame* frame) {
ASSERT(frame->is_entry_construct());
......@@ -259,7 +259,7 @@ class ExitFrame: public StackFrame {
public:
virtual Type type() const { return EXIT; }
virtual Code* FindCode() const;
virtual Code* code() const;
// Garbage collection support.
virtual void Iterate(ObjectVisitor* v) const;
......@@ -290,7 +290,7 @@ class ExitDebugFrame: public ExitFrame {
public:
virtual Type type() const { return EXIT_DEBUG; }
virtual Code* FindCode() const;
virtual Code* code() const;
static ExitDebugFrame* cast(StackFrame* frame) {
ASSERT(frame->is_exit_debug());
......@@ -399,7 +399,7 @@ class JavaScriptFrame: public StandardFrame {
int index) const;
// Determine the code for the frame.
virtual Code* FindCode() const;
virtual Code* code() const;
static JavaScriptFrame* cast(StackFrame* frame) {
ASSERT(frame->is_java_script());
......@@ -433,7 +433,7 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame {
virtual Type type() const { return ARGUMENTS_ADAPTOR; }
// Determine the code for the frame.
virtual Code* FindCode() const;
virtual Code* code() const;
static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
ASSERT(frame->is_arguments_adaptor());
......@@ -463,7 +463,7 @@ class InternalFrame: public StandardFrame {
virtual void Iterate(ObjectVisitor* v) const;
// Determine the code for the frame.
virtual Code* FindCode() const;
virtual Code* code() const;
static InternalFrame* cast(StackFrame* frame) {
ASSERT(frame->is_internal());
......
......@@ -419,11 +419,15 @@ void Heap::MarkCompact(GCTracer* tracer) {
tracer->set_full_gc_count(mc_count_);
LOG(ResourceEvent("markcompact", "begin"));
MarkCompactPrologue();
MarkCompactCollector::Prepare(tracer);
MarkCompactCollector::CollectGarbage(tracer);
bool is_compacting = MarkCompactCollector::IsCompacting();
MarkCompactEpilogue();
MarkCompactPrologue(is_compacting);
MarkCompactCollector::CollectGarbage();
MarkCompactEpilogue(is_compacting);
LOG(ResourceEvent("markcompact", "end"));
......@@ -435,18 +439,22 @@ void Heap::MarkCompact(GCTracer* tracer) {
}
void Heap::MarkCompactPrologue() {
void Heap::MarkCompactPrologue(bool is_compacting) {
// At any old GC clear the keyed lookup cache to enable collection of unused
// maps.
ClearKeyedLookupCache();
CompilationCache::MarkCompactPrologue();
RegExpImpl::OldSpaceCollectionPrologue();
Top::MarkCompactPrologue();
ThreadManager::MarkCompactPrologue();
Top::MarkCompactPrologue(is_compacting);
ThreadManager::MarkCompactPrologue(is_compacting);
}
void Heap::MarkCompactEpilogue() {
Top::MarkCompactEpilogue();
ThreadManager::MarkCompactEpilogue();
void Heap::MarkCompactEpilogue(bool is_compacting) {
Top::MarkCompactEpilogue(is_compacting);
ThreadManager::MarkCompactEpilogue(is_compacting);
}
......@@ -1601,7 +1609,7 @@ void Heap::CreateFillerObjectAt(Address addr, int size) {
Object* Heap::CreateCode(const CodeDesc& desc,
ScopeInfo<>* sinfo,
Code::Flags flags,
Code** self_reference) {
Handle<Object> self_reference) {
// Compute size
int body_size = RoundUp(desc.instr_size + desc.reloc_size, kObjectAlignment);
int sinfo_size = 0;
......@@ -1624,9 +1632,10 @@ Object* Heap::CreateCode(const CodeDesc& desc,
code->set_sinfo_size(sinfo_size);
code->set_flags(flags);
code->set_ic_flag(Code::IC_TARGET_IS_ADDRESS);
// Allow self references to created code object.
if (self_reference != NULL) {
*self_reference = code;
// Allow self references to created code object by patching the handle to
// point to the newly allocated Code object.
if (!self_reference.is_null()) {
*(self_reference.location()) = code;
}
// Migrate generated code.
// The generated code can contain Object** values (typically from handles)
......
......@@ -567,7 +567,7 @@ class Heap : public AllStatic {
static Object* CreateCode(const CodeDesc& desc,
ScopeInfo<>* sinfo,
Code::Flags flags,
Code** self_reference = NULL);
Handle<Object> self_reference);
static Object* CopyCode(Code* code);
// Finds the symbol for string in the symbol table.
......@@ -923,8 +923,8 @@ class Heap : public AllStatic {
static void MarkCompact(GCTracer* tracer);
// Code to be run before and after mark-compact.
static void MarkCompactPrologue();
static void MarkCompactEpilogue();
static void MarkCompactPrologue(bool is_compacting);
static void MarkCompactEpilogue(bool is_compacting);
// Helper function used by CopyObject to copy a source object to an
// allocated target object and update the forwarding pointer in the source
......
......@@ -43,7 +43,8 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
: Assembler(buffer, size),
unresolved_(0),
generating_stub_(false),
allow_stub_calls_(true) {
allow_stub_calls_(true),
code_object_(Heap::undefined_value()) {
}
......@@ -270,8 +271,8 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
mov(ip, Operand(Smi::FromInt(type)));
push(ip);
mov(ip, Operand(0));
push(ip); // Push an empty code cache slot.
mov(ip, Operand(CodeObject()));
push(ip);
add(fp, sp, Operand(3 * kPointerSize)); // Adjust FP to point to saved FP.
}
......
......@@ -230,6 +230,8 @@ class MacroAssembler: public Assembler {
};
List<Unresolved>* unresolved() { return &unresolved_; }
Handle<Object> CodeObject() { return code_object_; }
// ---------------------------------------------------------------------------
// StatsCounter support
......@@ -265,6 +267,8 @@ class MacroAssembler: public Assembler {
List<Unresolved> unresolved_;
bool generating_stub_;
bool allow_stub_calls_;
Handle<Object> code_object_; // This handle will be patched with the code
// object on installation.
// Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected,
......
......@@ -39,7 +39,8 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
: Assembler(buffer, size),
unresolved_(0),
generating_stub_(false),
allow_stub_calls_(true) {
allow_stub_calls_(true),
code_object_(Heap::undefined_value()) {
}
......@@ -317,7 +318,11 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
mov(ebp, Operand(esp));
push(esi);
push(Immediate(Smi::FromInt(type)));
push(Immediate(0)); // Push an empty code cache slot.
push(Immediate(CodeObject()));
if (FLAG_debug_code) {
cmp(Operand(esp, 0), Immediate(Factory::undefined_value()));
Check(not_equal, "code object not properly patched");
}
}
......
......@@ -235,6 +235,8 @@ class MacroAssembler: public Assembler {
};
List<Unresolved>* unresolved() { return &unresolved_; }
Handle<Object> CodeObject() { return code_object_; }
// ---------------------------------------------------------------------------
// StatsCounter support
......@@ -267,6 +269,8 @@ class MacroAssembler: public Assembler {
List<Unresolved> unresolved_;
bool generating_stub_;
bool allow_stub_calls_;
Handle<Object> code_object_; // This handle will be patched with the code
// code object on installation.
// Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected,
......
......@@ -58,11 +58,11 @@ int MarkCompactCollector::live_map_objects_ = 0;
int MarkCompactCollector::live_lo_objects_ = 0;
#endif
void MarkCompactCollector::CollectGarbage(GCTracer* tracer) {
// Rather than passing the tracer around we stash it in a static member
// variable.
tracer_ = tracer;
Prepare();
void MarkCompactCollector::CollectGarbage() {
// Make sure that Prepare() has been called. The individual steps below will
// update the state as they proceed.
ASSERT(state_ == PREPARE_GC);
// Prepare has selected whether to compact the old generation or not.
// Tell the tracer.
if (IsCompacting()) tracer_->set_is_compacting();
......@@ -96,7 +96,11 @@ void MarkCompactCollector::CollectGarbage(GCTracer* tracer) {
}
void MarkCompactCollector::Prepare() {
void MarkCompactCollector::Prepare(GCTracer* tracer) {
// Rather than passing the tracer around we stash it in a static member
// variable.
tracer_ = tracer;
static const int kFragmentationLimit = 50; // Percent.
#ifdef DEBUG
ASSERT(state_ == IDLE);
......@@ -241,7 +245,6 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
// Helper class for marking pointers in HeapObjects.
class MarkingVisitor : public ObjectVisitor {
public:
void VisitPointer(Object** p) {
MarkObjectByPointer(p);
}
......
......@@ -74,8 +74,12 @@ class MarkCompactCollector: public AllStatic {
// Type of functions to process non-live objects.
typedef void (*ProcessNonLiveFunction)(HeapObject* object);
// Prepares for GC by resetting relocation info in old and map spaces and
// choosing spaces to compact.
static void Prepare(GCTracer* tracer);
// Performs a global garbage collection.
static void CollectGarbage(GCTracer* tracer);
static void CollectGarbage();
// True if the last full GC performed heap compaction.
static bool HasCompacted() { return compacting_collection_; }
......@@ -123,10 +127,6 @@ class MarkCompactCollector: public AllStatic {
// collection (NULL before and after).
static GCTracer* tracer_;
// Prepares for GC by resetting relocation info in old and map spaces and
// choosing spaces to compact.
static void Prepare();
// Finishes GC, performs heap verification if enabled.
static void Finish();
......
......@@ -99,8 +99,7 @@ RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
start_label_(),
success_label_(),
backtrack_label_(),
exit_label_(),
self_(Heap::undefined_value()) {
exit_label_() {
__ jmp(&entry_label_); // We'll write the entry code later.
__ bind(&start_label_); // And then continue from here.
}
......@@ -145,7 +144,7 @@ void RegExpMacroAssemblerIA32::Backtrack() {
CheckPreemption();
// Pop Code* offset from backtrack stack, add Code* and jump to location.
Pop(ebx);
__ add(Operand(ebx), Immediate(self_));
__ add(Operand(ebx), Immediate(masm_->CodeObject()));
__ jmp(Operand(ebx));
}
......@@ -661,7 +660,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ bind(&stack_limit_hit);
int num_arguments = 2;
FrameAlign(num_arguments, ebx);
__ mov(Operand(esp, 1 * kPointerSize), Immediate(self_));
__ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
__ lea(eax, Operand(esp, -kPointerSize));
__ mov(Operand(esp, 0 * kPointerSize), eax);
CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
......@@ -784,7 +783,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ bind(&retry);
int num_arguments = 2;
FrameAlign(num_arguments, ebx);
__ mov(Operand(esp, 1 * kPointerSize), Immediate(self_));
__ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
__ lea(eax, Operand(esp, -kPointerSize));
__ mov(Operand(esp, 0 * kPointerSize), eax);
CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
......@@ -849,7 +848,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
Handle<Code> code = Factory::NewCode(code_desc,
NULL,
Code::ComputeFlags(Code::REGEXP),
self_);
masm_->CodeObject());
LOG(CodeCreateEvent("RegExp", *code, *(source->ToCString())));
return Handle<Object>::cast(code);
}
......@@ -1139,7 +1138,7 @@ void RegExpMacroAssemblerIA32::SafeCall(Label* to) {
void RegExpMacroAssemblerIA32::SafeReturn() {
__ pop(ebx);
__ add(Operand(ebx), Immediate(self_));
__ add(Operand(ebx), Immediate(masm_->CodeObject()));
__ jmp(Operand(ebx));
}
......
......@@ -253,9 +253,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
Label exit_label_;
Label check_preempt_label_;
Label stack_overflow_label_;
// Handle used to represent the generated code object itself.
Handle<Object> self_;
};
}} // namespace v8::internal
......
......@@ -5015,13 +5015,13 @@ static Object* Runtime_GetFrameDetails(Arguments args) {
Handle<Object> frame_id(WrapFrameId(it.frame()->id()));
// Find source position.
int position = it.frame()->FindCode()->SourcePosition(it.frame()->pc());
int position = it.frame()->code()->SourcePosition(it.frame()->pc());
// Check for constructor frame.
bool constructor = it.frame()->IsConstructor();
// Get code and read scope info from it for local variable information.
Handle<Code> code(it.frame()->FindCode());
Handle<Code> code(it.frame()->code());
ScopeInfo<> info(*code);
// Get the context.
......
......@@ -538,11 +538,9 @@ void PagedSpace::ClearRSet() {
Object* PagedSpace::FindObject(Address addr) {
#ifdef DEBUG
// Note: this function can only be called before or after mark-compact GC
// because it accesses map pointers.
ASSERT(!MarkCompactCollector::in_use());
#endif
if (!Contains(addr)) return Failure::Exception();
......
......@@ -892,7 +892,7 @@ Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
Object* StubCompiler::GetCodeWithFlags(Code::Flags flags) {
CodeDesc desc;
masm_.GetCode(&desc);
Object* result = Heap::CreateCode(desc, NULL, flags, NULL);
Object* result = Heap::CreateCode(desc, NULL, flags, masm_.CodeObject());
#ifdef DEBUG
if (FLAG_print_code_stubs && !result->IsFailure()) {
Code::cast(result)->Print();
......
......@@ -281,7 +281,7 @@ class StubCompiler BASE_EMBEDDED {
JSARRAY_HAS_FAST_ELEMENTS_CHECK
};
StubCompiler() : masm_(NULL, 256) { }
StubCompiler() : scope_(), masm_(NULL, 256) { }
Object* CompileCallInitialize(Code::Flags flags);
Object* CompileCallPreMonomorphic(Code::Flags flags);
......@@ -367,6 +367,7 @@ class StubCompiler BASE_EMBEDDED {
MacroAssembler* masm() { return &masm_; }
private:
HandleScope scope_;
MacroAssembler masm_;
};
......
......@@ -333,33 +333,37 @@ int Top::break_id() {
}
void Top::MarkCompactPrologue() {
MarkCompactPrologue(&thread_local_);
void Top::MarkCompactPrologue(bool is_compacting) {
MarkCompactPrologue(is_compacting, &thread_local_);
}
void Top::MarkCompactPrologue(char* data) {
MarkCompactPrologue(reinterpret_cast<ThreadLocalTop*>(data));
void Top::MarkCompactPrologue(bool is_compacting, char* data) {
MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
}
void Top::MarkCompactPrologue(ThreadLocalTop* thread) {
StackFrame::CookFramesForThread(thread);
void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) {
if (is_compacting) {
StackFrame::CookFramesForThread(thread);
}
}
void Top::MarkCompactEpilogue(char* data) {
MarkCompactEpilogue(reinterpret_cast<ThreadLocalTop*>(data));
void Top::MarkCompactEpilogue(bool is_compacting, char* data) {
MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
}
void Top::MarkCompactEpilogue() {
MarkCompactEpilogue(&thread_local_);
void Top::MarkCompactEpilogue(bool is_compacting) {
MarkCompactEpilogue(is_compacting, &thread_local_);
}
void Top::MarkCompactEpilogue(ThreadLocalTop* thread) {
StackFrame::UncookFramesForThread(thread);
void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) {
if (is_compacting) {
StackFrame::UncookFramesForThread(thread);
}
}
......@@ -690,7 +694,7 @@ void Top::PrintCurrentStackTrace(FILE* out) {
HandleScope scope;
// Find code position if recorded in relocation info.
JavaScriptFrame* frame = it.frame();
int pos = frame->FindCode()->SourcePosition(frame->pc());
int pos = frame->code()->SourcePosition(frame->pc());
Handle<Object> pos_obj(Smi::FromInt(pos));
// Fetch function and receiver.
Handle<JSFunction> fun(JSFunction::cast(frame->function()));
......@@ -721,7 +725,7 @@ void Top::ComputeLocation(MessageLocation* target) {
Object* script = fun->shared()->script();
if (script->IsScript() &&
!(Script::cast(script)->source()->IsUndefined())) {
int pos = frame->FindCode()->SourcePosition(frame->pc());
int pos = frame->code()->SourcePosition(frame->pc());
// Compute the location from the function and the reloc info.
Handle<Script> casted_script(Script::cast(script));
*target = MessageLocation(casted_script, pos, pos + 1);
......
......@@ -189,10 +189,12 @@ class Top {
static StackFrame::Id break_frame_id();
static int break_id();
static void MarkCompactPrologue();
static void MarkCompactEpilogue();
static void MarkCompactPrologue(char* archived_thread_data);
static void MarkCompactEpilogue(char* archived_thread_data);
static void MarkCompactPrologue(bool is_compacting);
static void MarkCompactEpilogue(bool is_compacting);
static void MarkCompactPrologue(bool is_compacting,
char* archived_thread_data);
static void MarkCompactEpilogue(bool is_compacting,
char* archived_thread_data);
static void PrintCurrentStackTrace(FILE* out);
static void PrintStackTrace(FILE* out, char* thread_data);
static void PrintStack(StringStream* accumulator);
......@@ -293,8 +295,10 @@ class Top {
static ThreadLocalTop thread_local_;
static void InitializeThreadLocal();
static void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
static void MarkCompactPrologue(ThreadLocalTop* archived_thread_data);
static void MarkCompactEpilogue(ThreadLocalTop* archived_thread_data);
static void MarkCompactPrologue(bool is_compacting,
ThreadLocalTop* archived_thread_data);
static void MarkCompactEpilogue(bool is_compacting,
ThreadLocalTop* archived_thread_data);
// Debug.
// Mutex for serializing access to break control structures.
......
......@@ -268,24 +268,24 @@ void ThreadManager::Iterate(ObjectVisitor* v) {
}
void ThreadManager::MarkCompactPrologue() {
void ThreadManager::MarkCompactPrologue(bool is_compacting) {
for (ThreadState* state = ThreadState::FirstInUse();
state != NULL;
state = state->Next()) {
char* data = state->data();
data += HandleScopeImplementer::ArchiveSpacePerThread();
Top::MarkCompactPrologue(data);
Top::MarkCompactPrologue(is_compacting, data);
}
}
void ThreadManager::MarkCompactEpilogue() {
void ThreadManager::MarkCompactEpilogue(bool is_compacting) {
for (ThreadState* state = ThreadState::FirstInUse();
state != NULL;
state = state->Next()) {
char* data = state->data();
data += HandleScopeImplementer::ArchiveSpacePerThread();
Top::MarkCompactEpilogue(data);
Top::MarkCompactEpilogue(is_compacting, data);
}
}
......
......@@ -74,8 +74,8 @@ class ThreadManager : public AllStatic {
static bool RestoreThread();
static void Iterate(ObjectVisitor* v);
static void MarkCompactPrologue();
static void MarkCompactEpilogue();
static void MarkCompactPrologue(bool is_compacting);
static void MarkCompactEpilogue(bool is_compacting);
static bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }
private:
static void EagerlyArchiveThread();
......
......@@ -72,7 +72,10 @@ TEST(0) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -106,7 +109,10 @@ TEST(1) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -149,7 +155,10 @@ TEST(2) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -194,7 +203,10 @@ TEST(3) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......
......@@ -69,7 +69,10 @@ TEST(AssemblerIa320) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -104,7 +107,10 @@ TEST(AssemblerIa321) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -143,7 +149,10 @@ TEST(AssemblerIa322) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -173,7 +182,10 @@ TEST(AssemblerIa323) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
// don't print the code - our disassembler can't handle cvttss2si
// instead print bytes
Disassembler::Dump(stdout,
......@@ -203,7 +215,10 @@ TEST(AssemblerIa324) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
// don't print the code - our disassembler can't handle cvttsd2si
// instead print bytes
Disassembler::Dump(stdout,
......@@ -230,7 +245,10 @@ TEST(AssemblerIa325) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
F0 f = FUNCTION_CAST<F0>(code->entry());
int res = f();
CHECK_EQ(42, res);
......@@ -263,7 +281,10 @@ TEST(AssemblerIa326) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
#ifdef DEBUG
::printf("\n---\n");
// don't print the code - our disassembler can't handle SSE instructions
......@@ -299,7 +320,10 @@ TEST(AssemblerIa328) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......@@ -352,7 +376,10 @@ TEST(AssemblerIa329) {
CodeDesc desc;
assm.GetCode(&desc);
Code* code =
Code::cast(Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)));
Code::cast(Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value())));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......
......@@ -368,7 +368,10 @@ TEST(DisasmIa320) {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
......
......@@ -77,7 +77,10 @@ static void CheckFindCodeObject() {
CodeDesc desc;
assm.GetCode(&desc);
Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* code = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(code->IsCode());
HeapObject* obj = HeapObject::cast(code);
......@@ -88,7 +91,10 @@ static void CheckFindCodeObject() {
CHECK_EQ(code, found);
}
Object* copy = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));
Object* copy = Heap::CreateCode(desc,
NULL,
Code::ComputeFlags(Code::STUB),
Handle<Object>(Heap::undefined_value()));
CHECK(copy->IsCode());
HeapObject* obj_copy = HeapObject::cast(copy);
Object* not_right = Heap::FindCodeObject(obj_copy->address() +
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment