Disentangle printing of stub names and memory allocation.

Using a C++-style method PrintName (a.k.a. << ;-), things get a lot easier when
two unrelated concerns are separated. Stubs don't need a name cache anymore,
simpler code while generating the stub name, memory allocation is centralized,
etc.
Review URL: http://codereview.chromium.org/7342042

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8627 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2011-07-13 11:08:25 +00:00
parent 6e2da733da
commit f1860fbdc0
10 changed files with 151 additions and 459 deletions

View File

@ -1683,25 +1683,17 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
}
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void UnaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name = NULL; // Make g++ happy.
switch (mode_) {
case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
return name_;
stream->Add("UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
}
@ -2037,12 +2029,7 @@ void BinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void BinaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name;
switch (mode_) {
@ -2051,13 +2038,10 @@ const char* BinaryOpStub::GetName() {
case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
default: overwrite_name = "UnknownOverwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
return name_;
stream->Add("BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
}
@ -4745,16 +4729,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
const char* CompareStub::GetName() {
void CompareStub::PrintName(StringStream* stream) {
ASSERT((lhs_.is(r0) && rhs_.is(r1)) ||
(lhs_.is(r1) && rhs_.is(r0)));
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
const char* cc_name;
switch (cc_) {
case lt: cc_name = "LT"; break;
@ -4765,40 +4742,14 @@ const char* CompareStub::GetName() {
case ne: cc_name = "NE"; break;
default: cc_name = "UnknownCondition"; break;
}
const char* lhs_name = lhs_.is(r0) ? "_r0" : "_r1";
const char* rhs_name = rhs_.is(r0) ? "_r0" : "_r1";
const char* strict_name = "";
if (strict_ && (cc_ == eq || cc_ == ne)) {
strict_name = "_STRICT";
}
const char* never_nan_nan_name = "";
if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
never_nan_nan_name = "_NO_NAN";
}
const char* include_number_compare_name = "";
if (!include_number_compare_) {
include_number_compare_name = "_NO_NUMBER";
}
const char* include_smi_compare_name = "";
if (!include_smi_compare_) {
include_smi_compare_name = "_NO_SMI";
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"CompareStub_%s%s%s%s%s%s",
cc_name,
lhs_name,
rhs_name,
strict_name,
never_nan_nan_name,
include_number_compare_name,
include_smi_compare_name);
return name_;
bool is_equality = cc_ == eq || cc_ == ne;
stream->Add("CompareStub_%s", cc_name);
stream->Add(lhs_.is(r0) ? "_r0" : "_r1");
stream->Add(rhs_.is(r0) ? "_r0" : "_r1");
if (strict_ && is_equality) stream->Add("_STRICT");
if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
if (!include_number_compare_) stream->Add("_NO_NUMBER");
if (!include_smi_compare_) stream->Add("_NO_SMI");
}

View File

@ -65,8 +65,7 @@ class UnaryOpStub: public CodeStub {
UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
: op_(op),
mode_(mode),
operand_type_(operand_type),
name_(NULL) {
operand_type_(operand_type) {
}
private:
@ -76,19 +75,7 @@ class UnaryOpStub: public CodeStub {
// Operand type information determined at runtime.
UnaryOpIC::TypeInfo operand_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
UnaryOpIC::GetName(operand_type_));
}
#endif
virtual void PrintName(StringStream* stream);
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
@ -142,8 +129,7 @@ class BinaryOpStub: public CodeStub {
: op_(op),
mode_(mode),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
result_type_(BinaryOpIC::UNINITIALIZED) {
use_vfp3_ = CpuFeatures::IsSupported(VFP3);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
@ -156,8 +142,7 @@ class BinaryOpStub: public CodeStub {
mode_(ModeBits::decode(key)),
use_vfp3_(VFP3Bits::decode(key)),
operands_type_(operands_type),
result_type_(result_type),
name_(NULL) { }
result_type_(result_type) { }
private:
enum SmiCodeGenerateHeapNumberResults {
@ -173,20 +158,7 @@ class BinaryOpStub: public CodeStub {
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
BinaryOpIC::GetName(operands_type_));
}
#endif
virtual void PrintName(StringStream* stream);
// Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
class ModeBits: public BitField<OverwriteMode, 0, 2> {};

View File

@ -61,21 +61,29 @@ void CodeStub::GenerateCode(MacroAssembler* masm) {
}
SmartPointer<const char> CodeStub::GetName() {
char buffer[100];
NoAllocationStringAllocator allocator(buffer,
static_cast<unsigned>(sizeof(buffer)));
StringStream stream(&allocator);
PrintName(&stream);
return stream.ToCString();
}
void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
code->set_major_key(MajorKey());
Isolate* isolate = masm->isolate();
PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
SmartPointer<const char> name = GetName();
PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
Counters* counters = isolate->counters();
counters->total_stubs_code_size()->Increment(code->instruction_size());
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code_stubs) {
#ifdef DEBUG
Print();
#endif
code->Disassemble(GetName());
code->Disassemble(*name);
PrintF("\n");
}
#endif
@ -213,13 +221,7 @@ void ICCompareStub::Generate(MacroAssembler* masm) {
}
const char* InstanceofStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void InstanceofStub::PrintName(StringStream* stream) {
const char* args = "";
if (HasArgsInRegisters()) {
args = "_REGS";
@ -235,12 +237,10 @@ const char* InstanceofStub::GetName() {
return_true_false_object = "_TRUEFALSE";
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"InstanceofStub%s%s%s",
args,
inline_check,
return_true_false_object);
return name_;
stream->Add("InstanceofStub%s%s%s",
args,
inline_check,
return_true_false_object);
}
@ -302,4 +302,30 @@ void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
}
void ArgumentsAccessStub::PrintName(StringStream* stream) {
const char* type_name = NULL; // Make g++ happy.
switch (type_) {
case READ_ELEMENT: type_name = "ReadElement"; break;
case NEW_NON_STRICT_FAST: type_name = "NewNonStrictFast"; break;
case NEW_NON_STRICT_SLOW: type_name = "NewNonStrictSlow"; break;
case NEW_STRICT: type_name = "NewStrict"; break;
}
stream->Add("ArgumentsAccessStub_%s", type_name);
}
void CallFunctionStub::PrintName(StringStream* stream) {
const char* in_loop_name = NULL; // Make g++ happy.
switch (in_loop_) {
case NOT_IN_LOOP: in_loop_name = ""; break;
case IN_LOOP: in_loop_name = "_InLoop"; break;
}
const char* flags_name = NULL; // Make g++ happy.
switch (flags_) {
case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
}
stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name);
}
} } // namespace v8::internal

View File

@ -181,16 +181,15 @@ class CodeStub BASE_EMBEDDED {
}
// Returns a name for logging/debugging purposes.
virtual const char* GetName() { return MajorName(MajorKey(), false); }
SmartPointer<const char> GetName();
virtual void PrintName(StringStream* stream) {
stream->Add("%s", MajorName(MajorKey(), false));
}
// Returns whether the code generated for this stub needs to be allocated as
// a fixed (non-moveable) code object.
virtual bool NeedsImmovableCode() { return false; }
#ifdef DEBUG
virtual void Print() { PrintF("%s\n", GetName()); }
#endif
// Computes the key based on major and minor.
uint32_t GetKey() {
ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
@ -362,7 +361,7 @@ class InstanceofStub: public CodeStub {
kReturnTrueFalseObject = 1 << 2
};
explicit InstanceofStub(Flags flags) : flags_(flags), name_(NULL) { }
explicit InstanceofStub(Flags flags) : flags_(flags) { }
static Register left();
static Register right();
@ -385,10 +384,9 @@ class InstanceofStub: public CodeStub {
return (flags_ & kReturnTrueFalseObject) != 0;
}
virtual const char* GetName();
virtual void PrintName(StringStream* stream);
Flags flags_;
char* name_;
};
@ -466,8 +464,7 @@ class CompareStub: public CodeStub {
include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
lhs_(lhs),
rhs_(rhs),
name_(NULL) { }
rhs_(rhs) { }
CompareStub(Condition cc,
bool strict,
@ -478,8 +475,7 @@ class CompareStub: public CodeStub {
include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
lhs_(no_reg),
rhs_(no_reg),
name_(NULL) { }
rhs_(no_reg) { }
void Generate(MacroAssembler* masm);
@ -533,26 +529,7 @@ class CompareStub: public CodeStub {
// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("CompareStub (minor %d) (cc %d), (strict %s), "
"(never_nan_nan %s), (smi_compare %s) (number_compare %s) ",
MinorKey(),
static_cast<int>(cc_),
strict_ ? "true" : "false",
never_nan_nan_ ? "true" : "false",
include_smi_compare_ ? "inluded" : "not included",
include_number_compare_ ? "included" : "not included");
if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) {
PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code());
} else {
PrintF("\n");
}
}
#endif
virtual void PrintName(StringStream* stream);
};
@ -610,7 +587,9 @@ class JSConstructEntryStub : public JSEntryStub {
private:
int MinorKey() { return 1; }
virtual const char* GetName() { return "JSConstructEntryStub"; }
virtual void PrintName(StringStream* stream) {
stream->Add("JSConstructEntryStub");
}
};
@ -637,11 +616,7 @@ class ArgumentsAccessStub: public CodeStub {
void GenerateNewNonStrictFast(MacroAssembler* masm);
void GenerateNewNonStrictSlow(MacroAssembler* masm);
#ifdef DEBUG
void Print() {
PrintF("ArgumentsAccessStub (type %d)\n", type_);
}
#endif
virtual void PrintName(StringStream* stream);
};
@ -685,14 +660,7 @@ class CallFunctionStub: public CodeStub {
InLoopFlag in_loop_;
CallFunctionFlags flags_;
#ifdef DEBUG
void Print() {
PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
argc_,
static_cast<int>(in_loop_),
static_cast<int>(flags_));
}
#endif
virtual void PrintName(StringStream* stream);
// Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
class InLoopBits: public BitField<InLoopFlag, 0, 1> {};

View File

@ -511,25 +511,17 @@ static void IntegerConvert(MacroAssembler* masm,
}
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void UnaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name = NULL; // Make g++ happy.
switch (mode_) {
case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
return name_;
stream->Add("UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
}
@ -914,12 +906,7 @@ void BinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void BinaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name;
switch (mode_) {
@ -928,13 +915,10 @@ const char* BinaryOpStub::GetName() {
case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
default: overwrite_name = "UnknownOverwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
return name_;
stream->Add("BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
}
@ -4726,15 +4710,8 @@ int CompareStub::MinorKey() {
// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
const char* CompareStub::GetName() {
void CompareStub::PrintName(StringStream* stream) {
ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
const char* cc_name;
switch (cc_) {
case less: cc_name = "LT"; break;
@ -4745,35 +4722,12 @@ const char* CompareStub::GetName() {
case not_equal: cc_name = "NE"; break;
default: cc_name = "UnknownCondition"; break;
}
const char* strict_name = "";
if (strict_ && (cc_ == equal || cc_ == not_equal)) {
strict_name = "_STRICT";
}
const char* never_nan_nan_name = "";
if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
never_nan_nan_name = "_NO_NAN";
}
const char* include_number_compare_name = "";
if (!include_number_compare_) {
include_number_compare_name = "_NO_NUMBER";
}
const char* include_smi_compare_name = "";
if (!include_smi_compare_) {
include_smi_compare_name = "_NO_SMI";
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"CompareStub_%s%s%s%s%s",
cc_name,
strict_name,
never_nan_nan_name,
include_number_compare_name,
include_smi_compare_name);
return name_;
bool is_equality = cc_ == equal || cc_ == not_equal;
stream->Add("CompareStub_%s", cc_name);
if (strict_ && is_equality) stream->Add("_STRICT");
if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
if (!include_number_compare_) stream->Add("_NO_NUMBER");
if (!include_smi_compare_) stream->Add("_NO_SMI");
}

View File

@ -67,8 +67,7 @@ class UnaryOpStub: public CodeStub {
UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
: op_(op),
mode_(mode),
operand_type_(operand_type),
name_(NULL) {
operand_type_(operand_type) {
}
private:
@ -78,19 +77,7 @@ class UnaryOpStub: public CodeStub {
// Operand type information determined at runtime.
UnaryOpIC::TypeInfo operand_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
UnaryOpIC::GetName(operand_type_));
}
#endif
virtual void PrintName(StringStream* stream);
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
@ -153,8 +140,7 @@ class BinaryOpStub: public CodeStub {
: op_(op),
mode_(mode),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
result_type_(BinaryOpIC::UNINITIALIZED) {
use_sse3_ = CpuFeatures::IsSupported(SSE3);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
@ -167,8 +153,7 @@ class BinaryOpStub: public CodeStub {
mode_(ModeBits::decode(key)),
use_sse3_(SSE3Bits::decode(key)),
operands_type_(operands_type),
result_type_(result_type),
name_(NULL) { }
result_type_(result_type) { }
private:
enum SmiCodeGenerateHeapNumberResults {
@ -184,20 +169,7 @@ class BinaryOpStub: public CodeStub {
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
BinaryOpIC::GetName(operands_type_));
}
#endif
virtual void PrintName(StringStream* stream);
// Minor key encoding in 16 bits RRRTTTSOOOOOOOMM.
class ModeBits: public BitField<OverwriteMode, 0, 2> {};

View File

@ -1797,25 +1797,17 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
}
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void UnaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name = NULL; // Make g++ happy.
switch (mode_) {
case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
return name_;
stream->Add("UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
}
@ -2154,12 +2146,7 @@ void BinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void BinaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name;
switch (mode_) {
@ -2168,13 +2155,10 @@ const char* BinaryOpStub::GetName() {
case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
default: overwrite_name = "UnknownOverwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
return name_;
stream->Add("BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
}
@ -4936,16 +4920,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
const char* CompareStub::GetName() {
void CompareStub::PrintName(StringStream* stream) {
ASSERT((lhs_.is(a0) && rhs_.is(a1)) ||
(lhs_.is(a1) && rhs_.is(a0)));
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
const char* cc_name;
switch (cc_) {
case lt: cc_name = "LT"; break;
@ -4956,40 +4933,14 @@ const char* CompareStub::GetName() {
case ne: cc_name = "NE"; break;
default: cc_name = "UnknownCondition"; break;
}
const char* lhs_name = lhs_.is(a0) ? "_a0" : "_a1";
const char* rhs_name = rhs_.is(a0) ? "_a0" : "_a1";
const char* strict_name = "";
if (strict_ && (cc_ == eq || cc_ == ne)) {
strict_name = "_STRICT";
}
const char* never_nan_nan_name = "";
if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
never_nan_nan_name = "_NO_NAN";
}
const char* include_number_compare_name = "";
if (!include_number_compare_) {
include_number_compare_name = "_NO_NUMBER";
}
const char* include_smi_compare_name = "";
if (!include_smi_compare_) {
include_smi_compare_name = "_NO_SMI";
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"CompareStub_%s%s%s%s%s%s",
cc_name,
lhs_name,
rhs_name,
strict_name,
never_nan_nan_name,
include_number_compare_name,
include_smi_compare_name);
return name_;
bool is_equality = cc_ == eq || cc_ == ne;
stream->Add("CompareStub_%s", cc_name);
stream->Add(lhs_.is(a0) ? "_a0" : "_a1");
stream->Add(rhs_.is(a0) ? "_a0" : "_a1");
if (strict_ && is_equality) stream->Add("_STRICT");
if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
if (!include_number_compare_) stream->Add("_NO_NUMBER");
if (!include_smi_compare_) stream->Add("_NO_SMI");
}

View File

@ -66,8 +66,7 @@ class UnaryOpStub: public CodeStub {
UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
: op_(op),
mode_(mode),
operand_type_(operand_type),
name_(NULL) {
operand_type_(operand_type) {
}
private:
@ -77,19 +76,7 @@ class UnaryOpStub: public CodeStub {
// Operand type information determined at runtime.
UnaryOpIC::TypeInfo operand_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
UnaryOpIC::GetName(operand_type_));
}
#endif
virtual void PrintName(StringStream* stream);
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
@ -143,8 +130,7 @@ class BinaryOpStub: public CodeStub {
: op_(op),
mode_(mode),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
result_type_(BinaryOpIC::UNINITIALIZED) {
use_fpu_ = CpuFeatures::IsSupported(FPU);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
@ -157,8 +143,7 @@ class BinaryOpStub: public CodeStub {
mode_(ModeBits::decode(key)),
use_fpu_(FPUBits::decode(key)),
operands_type_(operands_type),
result_type_(result_type),
name_(NULL) { }
result_type_(result_type) { }
private:
enum SmiCodeGenerateHeapNumberResults {
@ -174,20 +159,7 @@ class BinaryOpStub: public CodeStub {
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
BinaryOpIC::GetName(operands_type_));
}
#endif
virtual void PrintName(StringStream* stream);
// Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
class ModeBits: public BitField<OverwriteMode, 0, 2> {};

View File

@ -642,25 +642,17 @@ void UnaryOpStub::GenerateGenericCodeFallback(MacroAssembler* masm) {
}
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void UnaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name = NULL; // Make g++ happy.
switch (mode_) {
case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
return name_;
stream->Add("UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
UnaryOpIC::GetName(operand_type_));
}
@ -721,12 +713,7 @@ void BinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
void BinaryOpStub::PrintName(StringStream* stream) {
const char* op_name = Token::Name(op_);
const char* overwrite_name;
switch (mode_) {
@ -735,13 +722,10 @@ const char* BinaryOpStub::GetName() {
case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
default: overwrite_name = "UnknownOverwrite"; break;
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
return name_;
stream->Add("BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
BinaryOpIC::GetName(operands_type_));
}
@ -3766,15 +3750,8 @@ int CompareStub::MinorKey() {
// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
const char* CompareStub::GetName() {
void CompareStub::PrintName(StringStream* stream) {
ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
kMaxNameLength);
if (name_ == NULL) return "OOM";
const char* cc_name;
switch (cc_) {
case less: cc_name = "LT"; break;
@ -3785,35 +3762,12 @@ const char* CompareStub::GetName() {
case not_equal: cc_name = "NE"; break;
default: cc_name = "UnknownCondition"; break;
}
const char* strict_name = "";
if (strict_ && (cc_ == equal || cc_ == not_equal)) {
strict_name = "_STRICT";
}
const char* never_nan_nan_name = "";
if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
never_nan_nan_name = "_NO_NAN";
}
const char* include_number_compare_name = "";
if (!include_number_compare_) {
include_number_compare_name = "_NO_NUMBER";
}
const char* include_smi_compare_name = "";
if (!include_smi_compare_) {
include_smi_compare_name = "_NO_SMI";
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"CompareStub_%s%s%s%s",
cc_name,
strict_name,
never_nan_nan_name,
include_number_compare_name,
include_smi_compare_name);
return name_;
bool is_equality = cc_ == equal || cc_ == not_equal;
stream->Add("CompareStub_%s", cc_name);
if (strict_ && is_equality) stream->Add("_STRICT");
if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
if (!include_number_compare_) stream->Add("_NO_NUMBER");
if (!include_smi_compare_) stream->Add("_NO_SMI");
}

View File

@ -66,8 +66,7 @@ class UnaryOpStub: public CodeStub {
UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
: op_(op),
mode_(mode),
operand_type_(operand_type),
name_(NULL) {
operand_type_(operand_type) {
}
private:
@ -77,19 +76,7 @@ class UnaryOpStub: public CodeStub {
// Operand type information determined at runtime.
UnaryOpIC::TypeInfo operand_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
UnaryOpIC::GetName(operand_type_));
}
#endif
virtual void PrintName(StringStream* stream);
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
@ -149,8 +136,7 @@ class BinaryOpStub: public CodeStub {
: op_(op),
mode_(mode),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
result_type_(BinaryOpIC::UNINITIALIZED) {
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
@ -161,8 +147,7 @@ class BinaryOpStub: public CodeStub {
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operands_type_(operands_type),
result_type_(result_type),
name_(NULL) { }
result_type_(result_type) { }
private:
enum SmiCodeGenerateHeapNumberResults {
@ -177,20 +162,7 @@ class BinaryOpStub: public CodeStub {
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
virtual const char* GetName();
#ifdef DEBUG
void Print() {
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
BinaryOpIC::GetName(operands_type_));
}
#endif
virtual void PrintName(StringStream* stream);
// Minor key encoding in 15 bits RRRTTTOOOOOOOMM.
class ModeBits: public BitField<OverwriteMode, 0, 2> {};