Simplify and fix code aging.
Making the code size predictable is hard, and to make things even more complicated, the start of a function can contain various stuff like calls to a profiling hook, receiver adjustment or dynamic frame alignment. Instead of tackling all these problems separately, we now simply record the offset where patching should happen later in the Code object itself. Review URL: https://codereview.chromium.org/11316218 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13081 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
50dcf96e63
commit
5a4e0f1c79
@ -615,29 +615,6 @@ static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
||||
}
|
||||
|
||||
|
||||
byte* Code::FindPlatformCodeAgeSequence() {
|
||||
byte* start = instruction_start();
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
Memory::uint32_at(start) == kCodeAgePatchFirstInstruction) {
|
||||
return start;
|
||||
} else {
|
||||
byte* start_after_strict = NULL;
|
||||
if (kind() == FUNCTION) {
|
||||
start_after_strict = start + kSizeOfFullCodegenStrictModePrologue;
|
||||
} else {
|
||||
ASSERT(kind() == OPTIMIZED_FUNCTION);
|
||||
start_after_strict = start + kSizeOfOptimizedStrictModePrologue;
|
||||
}
|
||||
ASSERT(!memcmp(start_after_strict, young_sequence, young_length) ||
|
||||
Memory::uint32_at(start_after_strict) ==
|
||||
kCodeAgePatchFirstInstruction);
|
||||
return start_after_strict;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Code::IsYoungSequence(byte* sequence) {
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
|
@ -34,9 +34,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
static const int kSizeOfFullCodegenStrictModePrologue = 16;
|
||||
static const int kSizeOfOptimizedStrictModePrologue = 16;
|
||||
|
||||
// Forward declarations
|
||||
class CompilationInfo;
|
||||
|
||||
|
@ -149,15 +149,12 @@ void FullCodeGenerator::Generate() {
|
||||
// function calls.
|
||||
if (!info->is_classic_mode() || info->is_native()) {
|
||||
Label ok;
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
__ cmp(r5, Operand(0));
|
||||
__ b(eq, &ok);
|
||||
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
__ str(r2, MemOperand(sp, receiver_offset));
|
||||
__ bind(&ok);
|
||||
ASSERT_EQ(kSizeOfFullCodegenStrictModePrologue, ok.pos() - begin.pos());
|
||||
}
|
||||
|
||||
// Open a frame scope to indicate that there is a frame on the stack. The
|
||||
@ -167,6 +164,7 @@ void FullCodeGenerator::Generate() {
|
||||
|
||||
int locals_count = info->scope()->num_stack_slots();
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
// The following four instructions must remain together and unmodified for
|
||||
// code aging to work properly.
|
||||
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
|
||||
|
@ -138,17 +138,16 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// function calls.
|
||||
if (!info_->is_classic_mode() || info_->is_native()) {
|
||||
Label ok;
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
__ cmp(r5, Operand(0));
|
||||
__ b(eq, &ok);
|
||||
int receiver_offset = scope()->num_parameters() * kPointerSize;
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
__ str(r2, MemOperand(sp, receiver_offset));
|
||||
__ bind(&ok);
|
||||
ASSERT_EQ(kSizeOfOptimizedStrictModePrologue, ok.pos() - begin.pos());
|
||||
}
|
||||
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
// The following three instructions must remain together and unmodified for
|
||||
// code aging to work properly.
|
||||
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
|
||||
|
@ -107,6 +107,7 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
|
||||
if (!code.is_null()) {
|
||||
isolate->counters()->total_compiled_code_size()->Increment(
|
||||
code->instruction_size());
|
||||
code->set_prologue_offset(info->prologue_offset());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -52,57 +52,53 @@ namespace internal {
|
||||
|
||||
|
||||
CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone)
|
||||
: isolate_(script->GetIsolate()),
|
||||
flags_(LanguageModeField::encode(CLASSIC_MODE)),
|
||||
function_(NULL),
|
||||
scope_(NULL),
|
||||
global_scope_(NULL),
|
||||
: flags_(LanguageModeField::encode(CLASSIC_MODE)),
|
||||
script_(script),
|
||||
extension_(NULL),
|
||||
pre_parse_data_(NULL),
|
||||
osr_ast_id_(BailoutId::None()),
|
||||
zone_(zone),
|
||||
deferred_handles_(NULL) {
|
||||
Initialize(BASE);
|
||||
osr_ast_id_(BailoutId::None()) {
|
||||
Initialize(zone);
|
||||
}
|
||||
|
||||
|
||||
CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
|
||||
Zone* zone)
|
||||
: isolate_(shared_info->GetIsolate()),
|
||||
flags_(LanguageModeField::encode(CLASSIC_MODE) |
|
||||
IsLazy::encode(true)),
|
||||
function_(NULL),
|
||||
scope_(NULL),
|
||||
global_scope_(NULL),
|
||||
: flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
|
||||
shared_info_(shared_info),
|
||||
script_(Handle<Script>(Script::cast(shared_info->script()))),
|
||||
extension_(NULL),
|
||||
pre_parse_data_(NULL),
|
||||
osr_ast_id_(BailoutId::None()),
|
||||
zone_(zone),
|
||||
deferred_handles_(NULL) {
|
||||
Initialize(BASE);
|
||||
osr_ast_id_(BailoutId::None()) {
|
||||
Initialize(zone);
|
||||
}
|
||||
|
||||
|
||||
CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone)
|
||||
: isolate_(closure->GetIsolate()),
|
||||
flags_(LanguageModeField::encode(CLASSIC_MODE) |
|
||||
IsLazy::encode(true)),
|
||||
function_(NULL),
|
||||
scope_(NULL),
|
||||
global_scope_(NULL),
|
||||
: flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
|
||||
closure_(closure),
|
||||
shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
|
||||
script_(Handle<Script>(Script::cast(shared_info_->script()))),
|
||||
extension_(NULL),
|
||||
pre_parse_data_(NULL),
|
||||
context_(closure->context()),
|
||||
osr_ast_id_(BailoutId::None()),
|
||||
zone_(zone),
|
||||
deferred_handles_(NULL) {
|
||||
Initialize(BASE);
|
||||
osr_ast_id_(BailoutId::None()) {
|
||||
Initialize(zone);
|
||||
}
|
||||
|
||||
|
||||
void CompilationInfo::Initialize(Zone* zone) {
|
||||
isolate_ = script_->GetIsolate();
|
||||
function_ = NULL;
|
||||
scope_ = NULL;
|
||||
global_scope_ = NULL;
|
||||
extension_ = NULL;
|
||||
pre_parse_data_ = NULL;
|
||||
zone_ = zone;
|
||||
deferred_handles_ = NULL;
|
||||
prologue_offset_ = kPrologueOffsetNotSet;
|
||||
mode_ = V8::UseCrankshaft() ? BASE : NONOPT;
|
||||
if (script_->type()->value() == Script::TYPE_NATIVE) {
|
||||
MarkAsNative();
|
||||
}
|
||||
if (!shared_info_.is_null()) {
|
||||
ASSERT(language_mode() == CLASSIC_MODE);
|
||||
SetLanguageMode(shared_info_->language_mode());
|
||||
}
|
||||
set_bailout_reason("unknown");
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
static const int kPrologueOffsetNotSet = -1;
|
||||
|
||||
class ScriptDataImpl;
|
||||
|
||||
// CompilationInfo encapsulates some information known at compile time. It
|
||||
@ -186,6 +188,16 @@ class CompilationInfo {
|
||||
const char* bailout_reason() const { return bailout_reason_; }
|
||||
void set_bailout_reason(const char* reason) { bailout_reason_ = reason; }
|
||||
|
||||
int prologue_offset() const {
|
||||
ASSERT_NE(kPrologueOffsetNotSet, prologue_offset_);
|
||||
return prologue_offset_;
|
||||
}
|
||||
|
||||
void set_prologue_offset(int prologue_offset) {
|
||||
ASSERT_EQ(kPrologueOffsetNotSet, prologue_offset_);
|
||||
prologue_offset_ = prologue_offset;
|
||||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
|
||||
@ -200,18 +212,7 @@ class CompilationInfo {
|
||||
NONOPT
|
||||
};
|
||||
|
||||
void Initialize(Mode mode) {
|
||||
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
|
||||
ASSERT(!script_.is_null());
|
||||
if (script_->type()->value() == Script::TYPE_NATIVE) {
|
||||
MarkAsNative();
|
||||
}
|
||||
if (!shared_info_.is_null()) {
|
||||
ASSERT(language_mode() == CLASSIC_MODE);
|
||||
SetLanguageMode(shared_info_->language_mode());
|
||||
}
|
||||
set_bailout_reason("unknown");
|
||||
}
|
||||
void Initialize(Zone* zone);
|
||||
|
||||
void SetMode(Mode mode) {
|
||||
ASSERT(V8::UseCrankshaft());
|
||||
@ -285,6 +286,8 @@ class CompilationInfo {
|
||||
|
||||
const char* bailout_reason_;
|
||||
|
||||
int prologue_offset_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
|
||||
};
|
||||
|
||||
|
@ -3795,6 +3795,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
|
||||
code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
code->set_gc_metadata(Smi::FromInt(0));
|
||||
code->set_ic_age(global_ic_age_);
|
||||
code->set_prologue_offset(kPrologueOffsetNotSet);
|
||||
// Allow self references to created code object by patching the handle to
|
||||
// point to the newly allocated Code object.
|
||||
if (!self_reference.is_null()) {
|
||||
|
@ -872,42 +872,6 @@ static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
||||
}
|
||||
|
||||
|
||||
byte* Code::FindPlatformCodeAgeSequence() {
|
||||
byte* start = instruction_start();
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
*start == kCallOpcode) {
|
||||
return start;
|
||||
} else {
|
||||
if (kind() == FUNCTION) {
|
||||
byte* start_after_strict =
|
||||
start + kSizeOfFullCodegenStrictModePrologue;
|
||||
ASSERT(!memcmp(start_after_strict, young_sequence, young_length) ||
|
||||
start[kSizeOfFullCodegenStrictModePrologue] == kCallOpcode);
|
||||
return start_after_strict;
|
||||
} else {
|
||||
ASSERT(kind() == OPTIMIZED_FUNCTION);
|
||||
start = instruction_start() + kSizeOfOptimizedStrictModePrologue;
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
*start == kCallOpcode) {
|
||||
return start;
|
||||
}
|
||||
start = instruction_start() + kSizeOfOptimizedAlignStackPrologue;
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
*start == kCallOpcode) {
|
||||
return start;
|
||||
}
|
||||
start = instruction_start() + kSizeOfOptimizedAlignStackPrologue +
|
||||
kSizeOfOptimizedStrictModePrologue;
|
||||
ASSERT(!memcmp(start, young_sequence, young_length) ||
|
||||
*start == kCallOpcode);
|
||||
return start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Code::IsYoungSequence(byte* sequence) {
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
|
@ -37,10 +37,6 @@ namespace internal {
|
||||
// Forward declarations
|
||||
class CompilationInfo;
|
||||
|
||||
static const int kSizeOfFullCodegenStrictModePrologue = 34;
|
||||
static const int kSizeOfOptimizedStrictModePrologue = 12;
|
||||
static const int kSizeOfOptimizedAlignStackPrologue = 44;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CodeGenerator
|
||||
|
||||
|
@ -138,8 +138,6 @@ void FullCodeGenerator::Generate() {
|
||||
// function calls.
|
||||
if (!info->is_classic_mode() || info->is_native()) {
|
||||
Label ok;
|
||||
Label start;
|
||||
__ bind(&start);
|
||||
__ test(ecx, ecx);
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
// +1 for return address.
|
||||
@ -151,8 +149,6 @@ void FullCodeGenerator::Generate() {
|
||||
__ mov(Operand(esp, receiver_offset),
|
||||
Immediate(isolate()->factory()->undefined_value()));
|
||||
__ bind(&ok);
|
||||
ASSERT(!FLAG_age_code ||
|
||||
(kSizeOfFullCodegenStrictModePrologue == ok.pos() - start.pos()));
|
||||
}
|
||||
|
||||
// Open a frame scope to indicate that there is a frame on the stack. The
|
||||
@ -160,6 +156,7 @@ void FullCodeGenerator::Generate() {
|
||||
// the frame (that is done below).
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ push(ebp); // Caller's frame pointer.
|
||||
__ mov(ebp, esp);
|
||||
__ push(esi); // Callee's context.
|
||||
|
@ -140,8 +140,6 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// receiver object). ecx is zero for method calls and non-zero for
|
||||
// function calls.
|
||||
if (!info_->is_classic_mode() || info_->is_native()) {
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
Label ok;
|
||||
__ test(ecx, Operand(ecx));
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
@ -150,14 +148,10 @@ bool LCodeGen::GeneratePrologue() {
|
||||
__ mov(Operand(esp, receiver_offset),
|
||||
Immediate(isolate()->factory()->undefined_value()));
|
||||
__ bind(&ok);
|
||||
ASSERT(!FLAG_age_code ||
|
||||
(kSizeOfOptimizedStrictModePrologue == ok.pos() - begin.pos()));
|
||||
}
|
||||
|
||||
|
||||
if (dynamic_frame_alignment_) {
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
// Move state of dynamic frame alignment into edx.
|
||||
__ mov(edx, Immediate(kNoAlignmentPadding));
|
||||
|
||||
@ -180,11 +174,9 @@ bool LCodeGen::GeneratePrologue() {
|
||||
__ j(not_zero, &align_loop, Label::kNear);
|
||||
__ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
|
||||
__ bind(&do_not_pad);
|
||||
ASSERT(!FLAG_age_code ||
|
||||
(kSizeOfOptimizedAlignStackPrologue ==
|
||||
do_not_pad.pos() - begin.pos()));
|
||||
}
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
__ push(ebp); // Caller's frame pointer.
|
||||
__ mov(ebp, esp);
|
||||
__ push(esi); // Callee's context.
|
||||
|
@ -467,29 +467,6 @@ static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
||||
}
|
||||
|
||||
|
||||
byte* Code::FindPlatformCodeAgeSequence() {
|
||||
byte* start = instruction_start();
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
Memory::uint32_at(start) == kCodeAgePatchFirstInstruction) {
|
||||
return start;
|
||||
} else {
|
||||
byte* start_after_strict = NULL;
|
||||
if (kind() == FUNCTION) {
|
||||
start_after_strict = start + kSizeOfFullCodegenStrictModePrologue;
|
||||
} else {
|
||||
ASSERT(kind() == OPTIMIZED_FUNCTION);
|
||||
start_after_strict = start + kSizeOfOptimizedStrictModePrologue;
|
||||
}
|
||||
ASSERT(!memcmp(start_after_strict, young_sequence, young_length) ||
|
||||
Memory::uint32_at(start_after_strict) ==
|
||||
kCodeAgePatchFirstInstruction);
|
||||
return start_after_strict;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Code::IsYoungSequence(byte* sequence) {
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
|
@ -36,9 +36,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
static const int kSizeOfFullCodegenStrictModePrologue = 16;
|
||||
static const int kSizeOfOptimizedStrictModePrologue = 16;
|
||||
|
||||
// Forward declarations
|
||||
class CompilationInfo;
|
||||
|
||||
|
@ -158,14 +158,11 @@ void FullCodeGenerator::Generate() {
|
||||
// function calls.
|
||||
if (!info->is_classic_mode() || info->is_native()) {
|
||||
Label ok;
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
__ Branch(&ok, eq, t1, Operand(zero_reg));
|
||||
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
__ sw(a2, MemOperand(sp, receiver_offset));
|
||||
__ bind(&ok);
|
||||
ASSERT_EQ(kSizeOfFullCodegenStrictModePrologue, ok.pos() - begin.pos());
|
||||
}
|
||||
|
||||
// Open a frame scope to indicate that there is a frame on the stack. The
|
||||
@ -175,6 +172,7 @@ void FullCodeGenerator::Generate() {
|
||||
|
||||
int locals_count = info->scope()->num_stack_slots();
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
// The following three instructions must remain together and unmodified for
|
||||
// code aging to work properly.
|
||||
__ Push(ra, fp, cp, a1);
|
||||
|
@ -136,17 +136,15 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// function calls.
|
||||
if (!info_->is_classic_mode() || info_->is_native()) {
|
||||
Label ok;
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
__ Branch(&ok, eq, t1, Operand(zero_reg));
|
||||
|
||||
int receiver_offset = scope()->num_parameters() * kPointerSize;
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
__ sw(a2, MemOperand(sp, receiver_offset));
|
||||
__ bind(&ok);
|
||||
ASSERT_EQ(kSizeOfOptimizedStrictModePrologue, ok.pos() - begin.pos());
|
||||
}
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
// The following three instructions must remain together and unmodified for
|
||||
// code aging to work properly.
|
||||
__ Push(ra, fp, cp, a1);
|
||||
|
@ -4578,6 +4578,7 @@ JSMessageObject* JSMessageObject::cast(Object* obj) {
|
||||
|
||||
|
||||
INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
|
||||
INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
|
||||
ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
|
||||
ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
|
||||
ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
|
||||
|
@ -8875,11 +8875,10 @@ bool Code::IsOld() {
|
||||
|
||||
byte* Code::FindCodeAgeSequence() {
|
||||
return FLAG_age_code &&
|
||||
strlen(FLAG_stop_at) == 0 &&
|
||||
!ProfileEntryHookStub::HasEntryHook() &&
|
||||
prologue_offset() != kPrologueOffsetNotSet &&
|
||||
(kind() == OPTIMIZED_FUNCTION ||
|
||||
(kind() == FUNCTION && !has_debug_break_slots()))
|
||||
? FindPlatformCodeAgeSequence()
|
||||
? instruction_start() + prologue_offset()
|
||||
: NULL;
|
||||
}
|
||||
|
||||
|
@ -4325,6 +4325,11 @@ class Code: public HeapObject {
|
||||
inline void set_ic_age(int count);
|
||||
inline int ic_age();
|
||||
|
||||
// [prologue_offset]: Offset of the function prologue, used for aging
|
||||
// FUNCTIONs and OPTIMIZED_FUNCTIONs.
|
||||
inline int prologue_offset();
|
||||
inline void set_prologue_offset(int offset);
|
||||
|
||||
// Unchecked accessors to be used during GC.
|
||||
inline ByteArray* unchecked_relocation_info();
|
||||
inline FixedArray* unchecked_deoptimization_data();
|
||||
@ -4593,8 +4598,10 @@ class Code: public HeapObject {
|
||||
static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
|
||||
static const int kKindSpecificFlags2Offset =
|
||||
kKindSpecificFlags1Offset + kIntSize;
|
||||
// Note: We might be able to squeeze this into the flags above.
|
||||
static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
|
||||
|
||||
static const int kHeaderPaddingStart = kKindSpecificFlags2Offset + kIntSize;
|
||||
static const int kHeaderPaddingStart = kPrologueOffset + kIntSize;
|
||||
|
||||
// Add padding to align the instruction start following right after
|
||||
// the Code object header.
|
||||
@ -4688,7 +4695,6 @@ class Code: public HeapObject {
|
||||
static Code* GetCodeAgeStub(Age age, MarkingParity parity);
|
||||
|
||||
// Code aging -- platform-specific
|
||||
byte* FindPlatformCodeAgeSequence();
|
||||
static void PatchPlatformCodeAge(byte* sequence, Age age,
|
||||
MarkingParity parity);
|
||||
|
||||
|
@ -681,28 +681,6 @@ static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
||||
}
|
||||
|
||||
|
||||
byte* Code::FindPlatformCodeAgeSequence() {
|
||||
byte* start = instruction_start();
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
if (!memcmp(start, young_sequence, young_length) ||
|
||||
*start == kCallOpcode) {
|
||||
return start;
|
||||
} else {
|
||||
byte* start_after_strict = NULL;
|
||||
if (kind() == FUNCTION) {
|
||||
start_after_strict = start + kSizeOfFullCodegenStrictModePrologue;
|
||||
} else {
|
||||
ASSERT(kind() == OPTIMIZED_FUNCTION);
|
||||
start_after_strict = start + kSizeOfOptimizedStrictModePrologue;
|
||||
}
|
||||
ASSERT(!memcmp(start_after_strict, young_sequence, young_length) ||
|
||||
*start_after_strict == kCallOpcode);
|
||||
return start_after_strict;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Code::IsYoungSequence(byte* sequence) {
|
||||
uint32_t young_length;
|
||||
byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
||||
|
@ -39,9 +39,6 @@ class CompilationInfo;
|
||||
|
||||
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
|
||||
|
||||
static const int kSizeOfFullCodegenStrictModePrologue = 14;
|
||||
static const int kSizeOfOptimizedStrictModePrologue = 14;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CodeGenerator
|
||||
|
||||
|
@ -138,8 +138,6 @@ void FullCodeGenerator::Generate() {
|
||||
// function calls.
|
||||
if (!info->is_classic_mode() || info->is_native()) {
|
||||
Label ok;
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
__ testq(rcx, rcx);
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
// +1 for return address.
|
||||
@ -147,8 +145,6 @@ void FullCodeGenerator::Generate() {
|
||||
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
|
||||
__ movq(Operand(rsp, receiver_offset), kScratchRegister);
|
||||
__ bind(&ok);
|
||||
ASSERT(!FLAG_age_code ||
|
||||
(kSizeOfFullCodegenStrictModePrologue == ok.pos() - begin.pos()));
|
||||
}
|
||||
|
||||
// Open a frame scope to indicate that there is a frame on the stack. The
|
||||
@ -156,6 +152,7 @@ void FullCodeGenerator::Generate() {
|
||||
// the frame (that is done below).
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ push(rbp); // Caller's frame pointer.
|
||||
__ movq(rbp, rsp);
|
||||
__ push(rsi); // Callee's context.
|
||||
|
@ -133,8 +133,6 @@ bool LCodeGen::GeneratePrologue() {
|
||||
// object). rcx is zero for method calls and non-zero for function
|
||||
// calls.
|
||||
if (!info_->is_classic_mode() || info_->is_native()) {
|
||||
Label begin;
|
||||
__ bind(&begin);
|
||||
Label ok;
|
||||
__ testq(rcx, rcx);
|
||||
__ j(zero, &ok, Label::kNear);
|
||||
@ -143,10 +141,9 @@ bool LCodeGen::GeneratePrologue() {
|
||||
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
|
||||
__ movq(Operand(rsp, receiver_offset), kScratchRegister);
|
||||
__ bind(&ok);
|
||||
ASSERT(!FLAG_age_code ||
|
||||
(kSizeOfOptimizedStrictModePrologue == ok.pos() - begin.pos()));
|
||||
}
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
__ push(rbp); // Caller's frame pointer.
|
||||
__ movq(rbp, rsp);
|
||||
__ push(rsi); // Callee's context.
|
||||
|
Loading…
Reference in New Issue
Block a user