Rename TypeRecording...Stub into ...Stub.

There is no need for this long name.
Review URL: http://codereview.chromium.org/7063017

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8031 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2011-05-24 12:20:16 +00:00
parent 24222bdb57
commit 5552dbccdd
25 changed files with 614 additions and 632 deletions

View File

@ -1707,14 +1707,13 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
}
Handle<Code> GetTypeRecordingUnaryOpStub(int key,
TRUnaryOpIC::TypeInfo type_info) {
TypeRecordingUnaryOpStub stub(key, type_info);
Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
UnaryOpStub stub(key, type_info);
return stub.GetCode();
}
const char* TypeRecordingUnaryOpStub::GetName() {
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -1728,34 +1727,34 @@ const char* TypeRecordingUnaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingUnaryOpStub_%s_%s_%s",
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
return name_;
}
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::Generate(MacroAssembler* masm) {
void UnaryOpStub::Generate(MacroAssembler* masm) {
switch (operand_type_) {
case TRUnaryOpIC::UNINITIALIZED:
case UnaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRUnaryOpIC::SMI:
case UnaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRUnaryOpIC::HEAP_NUMBER:
case UnaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRUnaryOpIC::GENERIC:
case UnaryOpIC::GENERIC:
GenerateGenericStub(masm);
break;
}
}
void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Prepare to push argument.
__ mov(r3, Operand(r0));
@ -1768,7 +1767,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ Push(r3, r2, r1, r0);
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingUnaryOp_Patch),
ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
masm->isolate()),
4,
1);
@ -1776,7 +1775,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateSmiStubSub(masm);
@ -1790,7 +1789,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow);
__ bind(&non_smi);
@ -1799,7 +1798,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
Label non_smi;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -1807,9 +1806,9 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow) {
void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow) {
__ JumpIfNotSmi(r0, non_smi);
// The result of negating zero or the smallest negative smi is not a smi.
@ -1822,8 +1821,8 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
Label* non_smi) {
void UnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
Label* non_smi) {
__ JumpIfNotSmi(r0, non_smi);
// Flip bits and revert inverted smi-tag.
@ -1834,7 +1833,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateHeapNumberStubSub(masm);
@ -1848,7 +1847,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
__ bind(&non_smi);
@ -1860,8 +1859,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -1870,8 +1868,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
GenerateTypeTransition(masm);
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
EmitCheckForHeapNumber(masm, r0, r1, r6, slow);
// r0 is a heap number. Get a new heap number in r1.
if (mode_ == UNARY_OVERWRITE) {
@ -1903,7 +1901,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
void UnaryOpStub::GenerateHeapNumberCodeBitNot(
MacroAssembler* masm, Label* slow) {
EmitCheckForHeapNumber(masm, r0, r1, r6, slow);
// Convert the heap number is r0 to an untagged integer in r1.
@ -1954,7 +1952,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateGenericStubSub(masm);
@ -1968,7 +1966,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow);
__ bind(&non_smi);
@ -1978,7 +1976,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -1988,8 +1986,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericCodeFallback(MacroAssembler* masm) {
// Handle the slow case by jumping to the JavaScript builtin.
__ push(r0);
switch (op_) {
@ -2005,15 +2002,15 @@ void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
}
Handle<Code> GetTypeRecordingBinaryOpStub(int key,
TRBinaryOpIC::TypeInfo type_info,
TRBinaryOpIC::TypeInfo result_type_info) {
TypeRecordingBinaryOpStub stub(key, type_info, result_type_info);
Handle<Code> GetBinaryOpStub(int key,
BinaryOpIC::TypeInfo type_info,
BinaryOpIC::TypeInfo result_type_info) {
BinaryOpStub stub(key, type_info, result_type_info);
return stub.GetCode();
}
void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
Label get_result;
__ Push(r1, r0);
@ -2024,43 +2021,43 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ Push(r2, r1, r0);
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
masm->isolate()),
5,
1);
}
void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs(
void BinaryOpStub::GenerateTypeTransitionWithSavedArgs(
MacroAssembler* masm) {
UNIMPLEMENTED();
}
void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
void BinaryOpStub::Generate(MacroAssembler* masm) {
switch (operands_type_) {
case TRBinaryOpIC::UNINITIALIZED:
case BinaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRBinaryOpIC::SMI:
case BinaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
GenerateInt32Stub(masm);
break;
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRBinaryOpIC::ODDBALL:
case BinaryOpIC::ODDBALL:
GenerateOddballStub(masm);
break;
case TRBinaryOpIC::BOTH_STRING:
case BinaryOpIC::BOTH_STRING:
GenerateBothStringStub(masm);
break;
case TRBinaryOpIC::STRING:
case BinaryOpIC::STRING:
GenerateStringStub(masm);
break;
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::GENERIC:
GenerateGeneric(masm);
break;
default:
@ -2069,7 +2066,7 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* TypeRecordingBinaryOpStub::GetName() {
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -2085,16 +2082,15 @@ const char* TypeRecordingBinaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingBinaryOpStub_%s_%s_%s",
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
return name_;
}
void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) {
Register left = r1;
Register right = r0;
Register scratch1 = r7;
@ -2219,10 +2215,10 @@ void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
}
void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
bool smi_operands,
Label* not_numbers,
Label* gc_required) {
void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
bool smi_operands,
Label* not_numbers,
Label* gc_required) {
Register left = r1;
Register right = r0;
Register scratch1 = r7;
@ -2433,7 +2429,8 @@ void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
// generated. If the result is not a smi and heap number allocation is not
// requested the code falls through. If number allocation is requested but a
// heap number cannot be allocated the code jumps to the lable gc_required.
void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
void BinaryOpStub::GenerateSmiCode(
MacroAssembler* masm,
Label* use_runtime,
Label* gc_required,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
@ -2462,11 +2459,11 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
}
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
Label not_smis, call_runtime;
if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) {
if (result_type_ == BinaryOpIC::UNINITIALIZED ||
result_type_ == BinaryOpIC::SMI) {
// Only allow smi results.
GenerateSmiCode(masm, &call_runtime, NULL, NO_HEAPNUMBER_RESULTS);
} else {
@ -2487,19 +2484,19 @@ void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::STRING);
void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::STRING);
ASSERT(op_ == Token::ADD);
// Try to add arguments as strings, otherwise, transition to the generic
// TRBinaryOpIC type.
// BinaryOpIC type.
GenerateAddStrings(masm);
GenerateTypeTransition(masm);
}
void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
Label call_runtime;
ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
ASSERT(op_ == Token::ADD);
// If both arguments are strings, call the string add stub.
// Otherwise, do a transition.
@ -2527,8 +2524,8 @@ void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::INT32);
void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::INT32);
Register left = r1;
Register right = r0;
@ -2625,7 +2622,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
scratch1,
scratch2);
if (result_type_ <= TRBinaryOpIC::INT32) {
if (result_type_ <= BinaryOpIC::INT32) {
// If the ne condition is set, result does
// not fit in a 32-bit integer.
__ b(ne, &transition);
@ -2652,8 +2649,8 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// DIV just falls through to allocating a heap number.
}
if (result_type_ >= (op_ == Token::DIV) ? TRBinaryOpIC::HEAP_NUMBER
: TRBinaryOpIC::INT32) {
if (result_type_ >= (op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
: BinaryOpIC::INT32) {
__ bind(&return_heap_number);
// We are using vfp registers so r5 is available.
heap_number_result = r5;
@ -2762,12 +2759,13 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// The non vfp3 code does not support this special case, so jump to
// runtime if we don't support it.
if (CpuFeatures::IsSupported(VFP3)) {
__ b(mi,
(result_type_ <= TRBinaryOpIC::INT32) ? &transition
: &return_heap_number);
__ b(mi, (result_type_ <= BinaryOpIC::INT32)
? &transition
: &return_heap_number);
} else {
__ b(mi, (result_type_ <= TRBinaryOpIC::INT32) ? &transition
: &call_runtime);
__ b(mi, (result_type_ <= BinaryOpIC::INT32)
? &transition
: &call_runtime);
}
break;
case Token::SHL:
@ -2837,7 +2835,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
Label call_runtime;
if (op_ == Token::ADD) {
@ -2870,7 +2868,7 @@ void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
Label call_runtime;
GenerateFPOperation(masm, false, &call_runtime, &call_runtime);
@ -2879,7 +2877,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
Label call_runtime, call_string_add_or_runtime;
GenerateSmiCode(masm, &call_runtime, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
@ -2896,7 +2894,7 @@ void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD);
Label left_not_string, call_runtime;
@ -2927,7 +2925,7 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
GenerateRegisterArgsPush(masm);
switch (op_) {
case Token::ADD:
@ -2969,14 +2967,12 @@ void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
MacroAssembler* masm,
Register result,
Register heap_number_map,
Register scratch1,
Register scratch2,
Label* gc_required) {
void BinaryOpStub::GenerateHeapResultAllocation(MacroAssembler* masm,
Register result,
Register heap_number_map,
Register scratch1,
Register scratch2,
Label* gc_required) {
// Code below will scratch result if allocation fails. To keep both arguments
// intact for the runtime call result cannot be one of these.
ASSERT(!result.is(r0) && !result.is(r1));
@ -3003,7 +2999,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
}
void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
__ Push(r1, r0);
}

View File

@ -71,18 +71,18 @@ class ToBooleanStub: public CodeStub {
};
class TypeRecordingUnaryOpStub: public CodeStub {
class UnaryOpStub: public CodeStub {
public:
TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
: op_(op),
mode_(mode),
operand_type_(TRUnaryOpIC::UNINITIALIZED),
operand_type_(UnaryOpIC::UNINITIALIZED),
name_(NULL) {
}
TypeRecordingUnaryOpStub(
UnaryOpStub(
int key,
TRUnaryOpIC::TypeInfo operand_type)
UnaryOpIC::TypeInfo operand_type)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operand_type_(operand_type),
@ -94,7 +94,7 @@ class TypeRecordingUnaryOpStub: public CodeStub {
UnaryOverwriteMode mode_;
// Operand type information determined at runtime.
TRUnaryOpIC::TypeInfo operand_type_;
UnaryOpIC::TypeInfo operand_type_;
char* name_;
@ -102,20 +102,20 @@ class TypeRecordingUnaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingUnaryOpStub %d (op %s), "
PrintF("UnaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
}
#endif
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
Major MajorKey() { return TypeRecordingUnaryOp; }
Major MajorKey() { return UnaryOp; }
int MinorKey() {
return ModeBits::encode(mode_)
| OpBits::encode(op_)
@ -145,34 +145,34 @@ class TypeRecordingUnaryOpStub: public CodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRUnaryOpIC::ToState(operand_type_);
return UnaryOpIC::ToState(operand_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_unary_op_type(operand_type_);
code->set_unary_op_type(operand_type_);
}
};
class TypeRecordingBinaryOpStub: public CodeStub {
class BinaryOpStub: public CodeStub {
public:
TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
BinaryOpStub(Token::Value op, OverwriteMode mode)
: op_(op),
mode_(mode),
operands_type_(TRBinaryOpIC::UNINITIALIZED),
result_type_(TRBinaryOpIC::UNINITIALIZED),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
use_vfp3_ = CpuFeatures::IsSupported(VFP3);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
TypeRecordingBinaryOpStub(
BinaryOpStub(
int key,
TRBinaryOpIC::TypeInfo operands_type,
TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
BinaryOpIC::TypeInfo operands_type,
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
use_vfp3_(VFP3Bits::decode(key)),
@ -191,8 +191,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
bool use_vfp3_;
// Operand type information determined at runtime.
TRBinaryOpIC::TypeInfo operands_type_;
TRBinaryOpIC::TypeInfo result_type_;
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
@ -200,12 +200,12 @@ class TypeRecordingBinaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingBinaryOpStub %d (op %s), "
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
}
#endif
@ -213,10 +213,10 @@ class TypeRecordingBinaryOpStub: public CodeStub {
class ModeBits: public BitField<OverwriteMode, 0, 2> {};
class OpBits: public BitField<Token::Value, 2, 7> {};
class VFP3Bits: public BitField<bool, 9, 1> {};
class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {};
class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
Major MajorKey() { return TypeRecordingBinaryOp; }
Major MajorKey() { return BinaryOp; }
int MinorKey() {
return OpBits::encode(op_)
| ModeBits::encode(mode_)
@ -259,15 +259,15 @@ class TypeRecordingBinaryOpStub: public CodeStub {
void GenerateTypeTransition(MacroAssembler* masm);
void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRBinaryOpIC::ToState(operands_type_);
return BinaryOpIC::ToState(operands_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_binary_op_type(operands_type_);
code->set_type_recording_binary_op_result_type(result_type_);
code->set_binary_op_type(operands_type_);
code->set_binary_op_result_type(result_type_);
}
friend class CodeGenerator;

View File

@ -1717,14 +1717,14 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done);
__ bind(&smi_case);
// Smi case. This code works the same way as the smi-smi case in the type
// recording binary operation stub, see
// TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments.
// BinaryOpStub::GenerateSmiSmiOperation for comments.
switch (op) {
case Token::SAR:
__ b(&stub_call);
@ -1798,7 +1798,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ pop(r1);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), NULL, expr->id());
context()->Plug(r0);
}
@ -3790,8 +3790,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
UnaryOverwriteMode overwrite =
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
TypeRecordingUnaryOpStub stub(expr->op(), overwrite);
// TypeRecordingGenericUnaryOpStub expects the argument to be in the
UnaryOpStub stub(expr->op(), overwrite);
// UnaryOpStub expects the argument to be in the
// accumulator register r0.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
@ -3912,7 +3912,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE);
BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
__ bind(&done);

View File

@ -1093,7 +1093,7 @@ void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
__ mov(r0, right);
__ mov(r1, left);
}
TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT);
BinaryOpStub stub(op, OVERWRITE_LEFT);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
0,
@ -1399,7 +1399,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->InputAt(1)).is(r0));
ASSERT(ToRegister(instr->result()).is(r0));
TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}

View File

@ -38,8 +38,8 @@ namespace internal {
// as only the stubs up to and including Instanceof allows nested stub calls.
#define CODE_STUB_LIST_ALL_PLATFORMS(V) \
V(CallFunction) \
V(TypeRecordingUnaryOp) \
V(TypeRecordingBinaryOp) \
V(UnaryOp) \
V(BinaryOp) \
V(StringAdd) \
V(SubString) \
V(StringCompare) \
@ -55,7 +55,6 @@ namespace internal {
V(FastNewClosure) \
V(FastNewContext) \
V(FastCloneShallowArray) \
V(GenericUnaryOp) \
V(RevertToNumber) \
V(ToBoolean) \
V(ToNumber) \
@ -170,10 +169,10 @@ class CodeStub BASE_EMBEDDED {
// lazily generated function should be fully optimized or not.
virtual InLoopFlag InLoop() { return NOT_IN_LOOP; }
// TypeRecordingBinaryOpStub needs to override this.
// BinaryOpStub needs to override this.
virtual int GetCodeKind();
// TypeRecordingBinaryOpStub needs to override this.
// BinaryOpStub needs to override this.
virtual InlineCacheState GetICState() {
return UNINITIALIZED;
}

View File

@ -167,8 +167,8 @@ void BreakLocationIterator::Next() {
Address target = original_rinfo()->target_address();
Code* code = Code::GetCodeFromTargetAddress(target);
if ((code->is_inline_cache_stub() &&
!code->is_type_recording_binary_op_stub() &&
!code->is_type_recording_unary_op_stub() &&
!code->is_binary_op_stub() &&
!code->is_unary_op_stub() &&
!code->is_compare_ic_stub()) ||
RelocInfo::IsConstructCall(rmode())) {
break_point_++;

View File

@ -517,14 +517,13 @@ static void IntegerConvert(MacroAssembler* masm,
}
Handle<Code> GetTypeRecordingUnaryOpStub(int key,
TRUnaryOpIC::TypeInfo type_info) {
TypeRecordingUnaryOpStub stub(key, type_info);
Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
UnaryOpStub stub(key, type_info);
return stub.GetCode();
}
const char* TypeRecordingUnaryOpStub::GetName() {
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -538,34 +537,34 @@ const char* TypeRecordingUnaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingUnaryOpStub_%s_%s_%s",
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
return name_;
}
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::Generate(MacroAssembler* masm) {
void UnaryOpStub::Generate(MacroAssembler* masm) {
switch (operand_type_) {
case TRUnaryOpIC::UNINITIALIZED:
case UnaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRUnaryOpIC::SMI:
case UnaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRUnaryOpIC::HEAP_NUMBER:
case UnaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRUnaryOpIC::GENERIC:
case UnaryOpIC::GENERIC:
GenerateGenericStub(masm);
break;
}
}
void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ pop(ecx); // Save return address.
__ push(eax);
// the argument is now on top.
@ -580,15 +579,13 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingUnaryOp_Patch),
masm->isolate()),
4,
1);
ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
masm->isolate()), 4, 1);
}
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateSmiStubSub(masm);
@ -602,7 +599,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
Label non_smi, undo, slow;
GenerateSmiCodeSub(masm, &non_smi, &undo, &slow,
Label::kNear, Label::kNear, Label::kNear);
@ -614,7 +611,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
Label non_smi;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -622,13 +619,13 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* undo,
Label* slow,
Label::Distance non_smi_near,
Label::Distance undo_near,
Label::Distance slow_near) {
void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* undo,
Label* slow,
Label::Distance non_smi_near,
Label::Distance undo_near,
Label::Distance slow_near) {
// Check whether the value is a smi.
__ test(eax, Immediate(kSmiTagMask));
__ j(not_zero, non_smi, non_smi_near);
@ -646,7 +643,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(
void UnaryOpStub::GenerateSmiCodeBitNot(
MacroAssembler* masm,
Label* non_smi,
Label::Distance non_smi_near) {
@ -661,13 +658,13 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeUndo(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiCodeUndo(MacroAssembler* masm) {
__ mov(eax, Operand(edx));
}
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateHeapNumberStubSub(masm);
@ -681,7 +678,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, undo, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &undo, &call_builtin, Label::kNear);
__ bind(&non_smi);
@ -695,7 +692,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
void UnaryOpStub::GenerateHeapNumberStubBitNot(
MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
@ -706,8 +703,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
__ cmp(edx, masm->isolate()->factory()->heap_number_map());
__ j(not_equal, slow);
@ -742,9 +739,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeBitNot(MacroAssembler* masm,
Label* slow) {
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
__ cmp(edx, masm->isolate()->factory()->heap_number_map());
__ j(not_equal, slow);
@ -803,7 +799,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateGenericStubSub(masm);
@ -817,7 +813,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
Label non_smi, undo, slow;
GenerateSmiCodeSub(masm, &non_smi, &undo, &slow, Label::kNear);
__ bind(&non_smi);
@ -829,7 +825,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
__ bind(&non_smi);
@ -839,8 +835,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericCodeFallback(MacroAssembler* masm) {
// Handle the slow case by jumping to the corresponding JavaScript builtin.
__ pop(ecx); // pop return address.
__ push(eax);
@ -858,15 +853,15 @@ void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
}
Handle<Code> GetTypeRecordingBinaryOpStub(int key,
TRBinaryOpIC::TypeInfo type_info,
TRBinaryOpIC::TypeInfo result_type_info) {
TypeRecordingBinaryOpStub stub(key, type_info, result_type_info);
Handle<Code> GetBinaryOpStub(int key,
BinaryOpIC::TypeInfo type_info,
BinaryOpIC::TypeInfo result_type_info) {
BinaryOpStub stub(key, type_info, result_type_info);
return stub.GetCode();
}
void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ pop(ecx); // Save return address.
__ push(edx);
__ push(eax);
@ -882,7 +877,7 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
masm->isolate()),
5,
1);
@ -891,8 +886,7 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Prepare for a type transition runtime call when the args are already on
// the stack, under the return address.
void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs(
MacroAssembler* masm) {
void BinaryOpStub::GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm) {
__ pop(ecx); // Save return address.
// Left and right arguments are already on top of the stack.
// Push this stub's key. Although the operation and the type info are
@ -906,37 +900,37 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs(
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
masm->isolate()),
5,
1);
}
void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
void BinaryOpStub::Generate(MacroAssembler* masm) {
switch (operands_type_) {
case TRBinaryOpIC::UNINITIALIZED:
case BinaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRBinaryOpIC::SMI:
case BinaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
GenerateInt32Stub(masm);
break;
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRBinaryOpIC::ODDBALL:
case BinaryOpIC::ODDBALL:
GenerateOddballStub(masm);
break;
case TRBinaryOpIC::BOTH_STRING:
case BinaryOpIC::BOTH_STRING:
GenerateBothStringStub(masm);
break;
case TRBinaryOpIC::STRING:
case BinaryOpIC::STRING:
GenerateStringStub(masm);
break;
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::GENERIC:
GenerateGeneric(masm);
break;
default:
@ -945,7 +939,7 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* TypeRecordingBinaryOpStub::GetName() {
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -961,15 +955,16 @@ const char* TypeRecordingBinaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingBinaryOpStub_%s_%s_%s",
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
return name_;
}
void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
void BinaryOpStub::GenerateSmiCode(
MacroAssembler* masm,
Label* slow,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
// 1. Move arguments into edx, eax except for DIV and MOD, which need the
@ -1344,7 +1339,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
}
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
Label call_runtime;
switch (op_) {
@ -1366,8 +1361,8 @@ void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
UNREACHABLE();
}
if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) {
if (result_type_ == BinaryOpIC::UNINITIALIZED ||
result_type_ == BinaryOpIC::SMI) {
GenerateSmiCode(masm, &call_runtime, NO_HEAPNUMBER_RESULTS);
} else {
GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
@ -1395,19 +1390,19 @@ void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::STRING);
void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::STRING);
ASSERT(op_ == Token::ADD);
// Try to add arguments as strings, otherwise, transition to the generic
// TRBinaryOpIC type.
// BinaryOpIC type.
GenerateAddStrings(masm);
GenerateTypeTransition(masm);
}
void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
Label call_runtime;
ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
ASSERT(op_ == Token::ADD);
// If both arguments are strings, call the string add stub.
// Otherwise, do a transition.
@ -1437,9 +1432,9 @@ void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
Label call_runtime;
ASSERT(operands_type_ == TRBinaryOpIC::INT32);
ASSERT(operands_type_ == BinaryOpIC::INT32);
// Floating point case.
switch (op_) {
@ -1461,7 +1456,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
default: UNREACHABLE();
}
// Check result type if it is currently Int32.
if (result_type_ <= TRBinaryOpIC::INT32) {
if (result_type_ <= BinaryOpIC::INT32) {
__ cvttsd2si(ecx, Operand(xmm0));
__ cvtsi2sd(xmm2, Operand(ecx));
__ ucomisd(xmm0, xmm2);
@ -1639,7 +1634,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
if (op_ == Token::ADD) {
// Handle string addition here, because it is the only operation
// that does not do a ToNumber conversion on the operands.
@ -1672,7 +1667,7 @@ void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
Label call_runtime;
// Floating point case.
@ -1853,7 +1848,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
Label call_runtime;
Counters* counters = masm->isolate()->counters();
@ -2050,7 +2045,7 @@ void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD);
Label left_not_string, call_runtime;
@ -2084,7 +2079,7 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
void BinaryOpStub::GenerateHeapResultAllocation(
MacroAssembler* masm,
Label* alloc_failure) {
Label skip_allocation;
@ -2126,7 +2121,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
}
void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
__ pop(ecx);
__ push(edx);
__ push(eax);

View File

@ -72,18 +72,16 @@ class ToBooleanStub: public CodeStub {
};
class TypeRecordingUnaryOpStub: public CodeStub {
class UnaryOpStub: public CodeStub {
public:
TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
: op_(op),
mode_(mode),
operand_type_(TRUnaryOpIC::UNINITIALIZED),
operand_type_(UnaryOpIC::UNINITIALIZED),
name_(NULL) {
}
TypeRecordingUnaryOpStub(
int key,
TRUnaryOpIC::TypeInfo operand_type)
UnaryOpStub(int key, UnaryOpIC::TypeInfo operand_type)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operand_type_(operand_type),
@ -95,7 +93,7 @@ class TypeRecordingUnaryOpStub: public CodeStub {
UnaryOverwriteMode mode_;
// Operand type information determined at runtime.
TRUnaryOpIC::TypeInfo operand_type_;
UnaryOpIC::TypeInfo operand_type_;
char* name_;
@ -108,15 +106,15 @@ class TypeRecordingUnaryOpStub: public CodeStub {
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
}
#endif
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
Major MajorKey() { return TypeRecordingUnaryOp; }
Major MajorKey() { return UnaryOp; }
int MinorKey() {
return ModeBits::encode(mode_)
| OpBits::encode(op_)
@ -155,34 +153,34 @@ class TypeRecordingUnaryOpStub: public CodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRUnaryOpIC::ToState(operand_type_);
return UnaryOpIC::ToState(operand_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_unary_op_type(operand_type_);
code->set_unary_op_type(operand_type_);
}
};
class TypeRecordingBinaryOpStub: public CodeStub {
class BinaryOpStub: public CodeStub {
public:
TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
BinaryOpStub(Token::Value op, OverwriteMode mode)
: op_(op),
mode_(mode),
operands_type_(TRBinaryOpIC::UNINITIALIZED),
result_type_(TRBinaryOpIC::UNINITIALIZED),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
use_sse3_ = CpuFeatures::IsSupported(SSE3);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
TypeRecordingBinaryOpStub(
BinaryOpStub(
int key,
TRBinaryOpIC::TypeInfo operands_type,
TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
BinaryOpIC::TypeInfo operands_type,
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
use_sse3_(SSE3Bits::decode(key)),
@ -201,8 +199,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
bool use_sse3_;
// Operand type information determined at runtime.
TRBinaryOpIC::TypeInfo operands_type_;
TRBinaryOpIC::TypeInfo result_type_;
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
@ -210,12 +208,12 @@ class TypeRecordingBinaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingBinaryOpStub %d (op %s), "
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
}
#endif
@ -223,10 +221,10 @@ class TypeRecordingBinaryOpStub: public CodeStub {
class ModeBits: public BitField<OverwriteMode, 0, 2> {};
class OpBits: public BitField<Token::Value, 2, 7> {};
class SSE3Bits: public BitField<bool, 9, 1> {};
class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {};
class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
Major MajorKey() { return TypeRecordingBinaryOp; }
Major MajorKey() { return BinaryOp; }
int MinorKey() {
return OpBits::encode(op_)
| ModeBits::encode(mode_)
@ -257,15 +255,15 @@ class TypeRecordingBinaryOpStub: public CodeStub {
void GenerateTypeTransition(MacroAssembler* masm);
void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRBinaryOpIC::ToState(operands_type_);
return BinaryOpIC::ToState(operands_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_binary_op_type(operands_type_);
code->set_type_recording_binary_op_result_type(result_type_);
code->set_binary_op_type(operands_type_);
code->set_binary_op_result_type(result_type_);
}
friend class CodeGenerator;

View File

@ -1662,7 +1662,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ mov(eax, ecx);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done, Label::kNear);
@ -1745,7 +1745,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ pop(edx);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
// NULL signals no inlined smi code.
EmitCallIC(stub.GetCode(), NULL, expr->id());
context()->Plug(eax);
@ -3751,8 +3751,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
UnaryOverwriteMode overwrite =
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
TypeRecordingUnaryOpStub stub(expr->op(), overwrite);
// TypeRecordingUnaryOpStub expects the argument to be in the
UnaryOpStub stub(expr->op(), overwrite);
// UnaryOpStub expects the argument to be in the
// accumulator register eax.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
@ -3884,7 +3884,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Call stub for +1/-1.
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
__ bind(&done);

View File

@ -428,7 +428,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
// Signal that we don't inline smi code before these stubs in the
// optimizing code generator.
if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
if (code->kind() == Code::BINARY_OP_IC ||
code->kind() == Code::COMPARE_IC) {
__ nop();
}
@ -1300,7 +1300,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->InputAt(1)).is(eax));
ASSERT(ToRegister(instr->result()).is(eax));
TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
}

125
src/ic.cc
View File

@ -306,8 +306,8 @@ void IC::Clear(Address address) {
return KeyedStoreIC::Clear(address, target);
case Code::CALL_IC: return CallIC::Clear(address, target);
case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
case Code::TYPE_RECORDING_UNARY_OP_IC:
case Code::TYPE_RECORDING_BINARY_OP_IC:
case Code::UNARY_OP_IC:
case Code::BINARY_OP_IC:
case Code::COMPARE_IC:
// Clearing these is tricky and does not
// make any performance difference.
@ -2157,12 +2157,12 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
}
void TRUnaryOpIC::patch(Code* code) {
void UnaryOpIC::patch(Code* code) {
set_target(code);
}
const char* TRUnaryOpIC::GetName(TypeInfo type_info) {
const char* UnaryOpIC::GetName(TypeInfo type_info) {
switch (type_info) {
case UNINITIALIZED: return "Uninitialized";
case SMI: return "Smi";
@ -2173,7 +2173,7 @@ const char* TRUnaryOpIC::GetName(TypeInfo type_info) {
}
TRUnaryOpIC::State TRUnaryOpIC::ToState(TypeInfo type_info) {
UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
switch (type_info) {
case UNINITIALIZED:
return ::v8::internal::UNINITIALIZED;
@ -2187,7 +2187,7 @@ TRUnaryOpIC::State TRUnaryOpIC::ToState(TypeInfo type_info) {
return ::v8::internal::UNINITIALIZED;
}
TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) {
UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
::v8::internal::TypeInfo operand_type =
::v8::internal::TypeInfo::TypeFromValue(operand);
if (operand_type.IsSmi()) {
@ -2200,34 +2200,34 @@ TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) {
}
TRUnaryOpIC::TypeInfo TRUnaryOpIC::ComputeNewType(
TRUnaryOpIC::TypeInfo type,
TRUnaryOpIC::TypeInfo previous) {
switch (previous) {
case TRUnaryOpIC::UNINITIALIZED:
return type;
case TRUnaryOpIC::SMI:
return (type == TRUnaryOpIC::GENERIC)
? TRUnaryOpIC::GENERIC
: TRUnaryOpIC::HEAP_NUMBER;
case TRUnaryOpIC::HEAP_NUMBER:
return TRUnaryOpIC::GENERIC;
case TRUnaryOpIC::GENERIC:
UnaryOpIC::TypeInfo UnaryOpIC::ComputeNewType(
UnaryOpIC::TypeInfo current_type,
UnaryOpIC::TypeInfo previous_type) {
switch (previous_type) {
case UnaryOpIC::UNINITIALIZED:
return current_type;
case UnaryOpIC::SMI:
return (current_type == UnaryOpIC::GENERIC)
? UnaryOpIC::GENERIC
: UnaryOpIC::HEAP_NUMBER;
case UnaryOpIC::HEAP_NUMBER:
return UnaryOpIC::GENERIC;
case UnaryOpIC::GENERIC:
// We should never do patching if we are in GENERIC state.
UNREACHABLE();
return TRUnaryOpIC::GENERIC;
return UnaryOpIC::GENERIC;
}
UNREACHABLE();
return TRUnaryOpIC::GENERIC;
return UnaryOpIC::GENERIC;
}
void TRBinaryOpIC::patch(Code* code) {
void BinaryOpIC::patch(Code* code) {
set_target(code);
}
const char* TRBinaryOpIC::GetName(TypeInfo type_info) {
const char* BinaryOpIC::GetName(TypeInfo type_info) {
switch (type_info) {
case UNINITIALIZED: return "Uninitialized";
case SMI: return "SMI";
@ -2242,7 +2242,7 @@ const char* TRBinaryOpIC::GetName(TypeInfo type_info) {
}
TRBinaryOpIC::State TRBinaryOpIC::ToState(TypeInfo type_info) {
BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
switch (type_info) {
case UNINITIALIZED:
return ::v8::internal::UNINITIALIZED;
@ -2261,8 +2261,8 @@ TRBinaryOpIC::State TRBinaryOpIC::ToState(TypeInfo type_info) {
}
TRBinaryOpIC::TypeInfo TRBinaryOpIC::JoinTypes(TRBinaryOpIC::TypeInfo x,
TRBinaryOpIC::TypeInfo y) {
BinaryOpIC::TypeInfo BinaryOpIC::JoinTypes(BinaryOpIC::TypeInfo x,
BinaryOpIC::TypeInfo y) {
if (x == UNINITIALIZED) return y;
if (y == UNINITIALIZED) return x;
if (x == y) return x;
@ -2276,8 +2276,8 @@ TRBinaryOpIC::TypeInfo TRBinaryOpIC::JoinTypes(TRBinaryOpIC::TypeInfo x,
}
TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left,
Handle<Object> right) {
BinaryOpIC::TypeInfo BinaryOpIC::GetTypeInfo(Handle<Object> left,
Handle<Object> right) {
::v8::internal::TypeInfo left_type =
::v8::internal::TypeInfo::TypeFromValue(left);
::v8::internal::TypeInfo right_type =
@ -2315,32 +2315,31 @@ TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left,
// defined in code-stubs-<arch>.cc
// Only needed to remove dependency of ic.cc on code-stubs-<arch>.h.
Handle<Code> GetTypeRecordingUnaryOpStub(int key,
TRUnaryOpIC::TypeInfo type_info);
Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info);
RUNTIME_FUNCTION(MaybeObject*, TypeRecordingUnaryOp_Patch) {
RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
ASSERT(args.length() == 4);
HandleScope scope(isolate);
Handle<Object> operand = args.at<Object>(0);
int key = Smi::cast(args[1])->value();
Token::Value op = static_cast<Token::Value>(Smi::cast(args[2])->value());
TRUnaryOpIC::TypeInfo previous_type =
static_cast<TRUnaryOpIC::TypeInfo>(Smi::cast(args[3])->value());
UnaryOpIC::TypeInfo previous_type =
static_cast<UnaryOpIC::TypeInfo>(Smi::cast(args[3])->value());
TRUnaryOpIC::TypeInfo type = TRUnaryOpIC::GetTypeInfo(operand);
type = TRUnaryOpIC::ComputeNewType(type, previous_type);
UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand);
type = UnaryOpIC::ComputeNewType(type, previous_type);
Handle<Code> code = GetTypeRecordingUnaryOpStub(key, type);
Handle<Code> code = GetUnaryOpStub(key, type);
if (!code.is_null()) {
if (FLAG_trace_ic) {
PrintF("[TypeRecordingUnaryOpIC (%s->%s)#%s]\n",
TRUnaryOpIC::GetName(previous_type),
TRUnaryOpIC::GetName(type),
PrintF("[UnaryOpIC (%s->%s)#%s]\n",
UnaryOpIC::GetName(previous_type),
UnaryOpIC::GetName(type),
Token::Name(op));
}
TRUnaryOpIC ic(isolate);
UnaryOpIC ic(isolate);
ic.patch(*code);
}
@ -2371,12 +2370,12 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingUnaryOp_Patch) {
// defined in code-stubs-<arch>.cc
// Only needed to remove dependency of ic.cc on code-stubs-<arch>.h.
Handle<Code> GetTypeRecordingBinaryOpStub(int key,
TRBinaryOpIC::TypeInfo type_info,
TRBinaryOpIC::TypeInfo result_type);
Handle<Code> GetBinaryOpStub(int key,
BinaryOpIC::TypeInfo type_info,
BinaryOpIC::TypeInfo result_type);
RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) {
RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
ASSERT(args.length() == 5);
HandleScope scope(isolate);
@ -2384,17 +2383,17 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) {
Handle<Object> right = args.at<Object>(1);
int key = Smi::cast(args[2])->value();
Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value());
TRBinaryOpIC::TypeInfo previous_type =
static_cast<TRBinaryOpIC::TypeInfo>(Smi::cast(args[4])->value());
BinaryOpIC::TypeInfo previous_type =
static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value());
TRBinaryOpIC::TypeInfo type = TRBinaryOpIC::GetTypeInfo(left, right);
type = TRBinaryOpIC::JoinTypes(type, previous_type);
TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED;
if ((type == TRBinaryOpIC::STRING || type == TRBinaryOpIC::BOTH_STRING) &&
BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(left, right);
type = BinaryOpIC::JoinTypes(type, previous_type);
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED;
if ((type == BinaryOpIC::STRING || type == BinaryOpIC::BOTH_STRING) &&
op != Token::ADD) {
type = TRBinaryOpIC::GENERIC;
type = BinaryOpIC::GENERIC;
}
if (type == TRBinaryOpIC::SMI && previous_type == TRBinaryOpIC::SMI) {
if (type == BinaryOpIC::SMI && previous_type == BinaryOpIC::SMI) {
if (op == Token::DIV ||
op == Token::MUL ||
op == Token::SHR ||
@ -2403,31 +2402,31 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) {
// That is the only way to get here from the Smi stub.
// With 32-bit Smis, all overflows give heap numbers, but with
// 31-bit Smis, most operations overflow to int32 results.
result_type = TRBinaryOpIC::HEAP_NUMBER;
result_type = BinaryOpIC::HEAP_NUMBER;
} else {
// Other operations on SMIs that overflow yield int32s.
result_type = TRBinaryOpIC::INT32;
result_type = BinaryOpIC::INT32;
}
}
if (type == TRBinaryOpIC::INT32 && previous_type == TRBinaryOpIC::INT32) {
if (type == BinaryOpIC::INT32 && previous_type == BinaryOpIC::INT32) {
// We must be here because an operation on two INT32 types overflowed.
result_type = TRBinaryOpIC::HEAP_NUMBER;
result_type = BinaryOpIC::HEAP_NUMBER;
}
Handle<Code> code = GetTypeRecordingBinaryOpStub(key, type, result_type);
Handle<Code> code = GetBinaryOpStub(key, type, result_type);
if (!code.is_null()) {
if (FLAG_trace_ic) {
PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n",
TRBinaryOpIC::GetName(previous_type),
TRBinaryOpIC::GetName(type),
TRBinaryOpIC::GetName(result_type),
PrintF("[BinaryOpIC (%s->(%s->%s))#%s]\n",
BinaryOpIC::GetName(previous_type),
BinaryOpIC::GetName(type),
BinaryOpIC::GetName(result_type),
Token::Name(op));
}
TRBinaryOpIC ic(isolate);
BinaryOpIC ic(isolate);
ic.patch(*code);
// Activate inlined smi code.
if (previous_type == TRBinaryOpIC::UNINITIALIZED) {
if (previous_type == BinaryOpIC::UNINITIALIZED) {
PatchInlinedSmiCode(ic.address());
}
}

View File

@ -56,8 +56,8 @@ namespace internal {
ICU(LoadPropertyWithInterceptorForCall) \
ICU(KeyedLoadPropertyWithInterceptor) \
ICU(StoreInterceptorProperty) \
ICU(TypeRecordingUnaryOp_Patch) \
ICU(TypeRecordingBinaryOp_Patch) \
ICU(UnaryOp_Patch) \
ICU(BinaryOp_Patch) \
ICU(CompareIC_Miss)
//
// IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC,
@ -621,7 +621,7 @@ class KeyedStoreIC: public KeyedIC {
};
class TRUnaryOpIC: public IC {
class UnaryOpIC: public IC {
public:
// sorted: increasingly more unspecific (ignoring UNINITIALIZED)
@ -633,7 +633,7 @@ class TRUnaryOpIC: public IC {
GENERIC
};
explicit TRUnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
void patch(Code* code);
@ -648,7 +648,7 @@ class TRUnaryOpIC: public IC {
// Type Recording BinaryOpIC, that records the types of the inputs and outputs.
class TRBinaryOpIC: public IC {
class BinaryOpIC: public IC {
public:
enum TypeInfo {
@ -662,7 +662,7 @@ class TRBinaryOpIC: public IC {
GENERIC
};
explicit TRBinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
void patch(Code* code);
@ -716,7 +716,7 @@ class CompareIC: public IC {
Token::Value op_;
};
// Helper for TRBinaryOpIC and CompareIC.
// Helper for BinaryOpIC and CompareIC.
void PatchInlinedSmiCode(Address address);
} } // namespace v8::internal

View File

@ -1604,8 +1604,8 @@ void Logger::LogCodeObject(Object* object) {
case Code::FUNCTION:
case Code::OPTIMIZED_FUNCTION:
return; // We log this later using LogCompiledFunctions.
case Code::TYPE_RECORDING_UNARY_OP_IC: // fall through
case Code::TYPE_RECORDING_BINARY_OP_IC: // fall through
case Code::UNARY_OP_IC: // fall through
case Code::BINARY_OP_IC: // fall through
case Code::COMPARE_IC: // fall through
case Code::STUB:
description =

View File

@ -1807,14 +1807,13 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
}
Handle<Code> GetTypeRecordingUnaryOpStub(int key,
TRUnaryOpIC::TypeInfo type_info) {
TypeRecordingUnaryOpStub stub(key, type_info);
Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
UnaryOpStub stub(key, type_info);
return stub.GetCode();
}
const char* TypeRecordingUnaryOpStub::GetName() {
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -1828,34 +1827,34 @@ const char* TypeRecordingUnaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingUnaryOpStub_%s_%s_%s",
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
return name_;
}
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::Generate(MacroAssembler* masm) {
void UnaryOpStub::Generate(MacroAssembler* masm) {
switch (operand_type_) {
case TRUnaryOpIC::UNINITIALIZED:
case UnaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRUnaryOpIC::SMI:
case UnaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRUnaryOpIC::HEAP_NUMBER:
case UnaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRUnaryOpIC::GENERIC:
case UnaryOpIC::GENERIC:
GenerateGenericStub(masm);
break;
}
}
void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Argument is in a0 and v0 at this point, so we can overwrite a0.
// Push this stub's key. Although the operation and the type info are
// encoded into the key, the encoding is opaque, so push them too.
@ -1866,7 +1865,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ Push(v0, a2, a1, a0);
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingUnaryOp_Patch),
ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
masm->isolate()),
4,
1);
@ -1874,7 +1873,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateSmiStubSub(masm);
@ -1888,7 +1887,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow);
__ bind(&non_smi);
@ -1897,7 +1896,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
Label non_smi;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -1905,9 +1904,9 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow) {
void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow) {
__ JumpIfNotSmi(a0, non_smi);
// The result of negating zero or the smallest negative smi is not a smi.
@ -1920,8 +1919,8 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
Label* non_smi) {
void UnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
Label* non_smi) {
__ JumpIfNotSmi(a0, non_smi);
// Flip bits and revert inverted smi-tag.
@ -1932,7 +1931,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateHeapNumberStubSub(masm);
@ -1946,7 +1945,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
__ bind(&non_smi);
@ -1958,8 +1957,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -1968,8 +1966,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
GenerateTypeTransition(masm);
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
EmitCheckForHeapNumber(masm, a0, a1, t2, slow);
// a0 is a heap number. Get a new heap number in a1.
if (mode_ == UNARY_OVERWRITE) {
@ -2001,8 +1999,9 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
MacroAssembler* masm, Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeBitNot(
MacroAssembler* masm,
Label* slow) {
EmitCheckForHeapNumber(masm, a0, a1, t2, slow);
// Convert the heap number in a0 to an untagged integer in a1.
__ ConvertToInt32(a0, a1, a2, a3, f0, slow);
@ -2051,7 +2050,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateGenericStubSub(masm);
@ -2065,7 +2064,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow);
__ bind(&non_smi);
@ -2075,7 +2074,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi);
__ bind(&non_smi);
@ -2085,7 +2084,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
void UnaryOpStub::GenerateGenericCodeFallback(
MacroAssembler* masm) {
// Handle the slow case by jumping to the JavaScript builtin.
__ push(a0);
@ -2102,15 +2101,15 @@ void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
}
Handle<Code> GetTypeRecordingBinaryOpStub(int key,
TRBinaryOpIC::TypeInfo type_info,
TRBinaryOpIC::TypeInfo result_type_info) {
TypeRecordingBinaryOpStub stub(key, type_info, result_type_info);
Handle<Code> GetBinaryOpStub(int key,
BinaryOpIC::TypeInfo type_info,
BinaryOpIC::TypeInfo result_type_info) {
BinaryOpStub stub(key, type_info, result_type_info);
return stub.GetCode();
}
void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
Label get_result;
__ Push(a1, a0);
@ -2121,43 +2120,43 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ Push(a2, a1, a0);
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
masm->isolate()),
5,
1);
}
void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs(
void BinaryOpStub::GenerateTypeTransitionWithSavedArgs(
MacroAssembler* masm) {
UNIMPLEMENTED();
}
void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
void BinaryOpStub::Generate(MacroAssembler* masm) {
switch (operands_type_) {
case TRBinaryOpIC::UNINITIALIZED:
case BinaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRBinaryOpIC::SMI:
case BinaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
GenerateInt32Stub(masm);
break;
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRBinaryOpIC::ODDBALL:
case BinaryOpIC::ODDBALL:
GenerateOddballStub(masm);
break;
case TRBinaryOpIC::BOTH_STRING:
case BinaryOpIC::BOTH_STRING:
GenerateBothStringStub(masm);
break;
case TRBinaryOpIC::STRING:
case BinaryOpIC::STRING:
GenerateStringStub(masm);
break;
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::GENERIC:
GenerateGeneric(masm);
break;
default:
@ -2166,7 +2165,7 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* TypeRecordingBinaryOpStub::GetName() {
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -2182,17 +2181,16 @@ const char* TypeRecordingBinaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingBinaryOpStub_%s_%s_%s",
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
return name_;
}
void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) {
Register left = a1;
Register right = a0;
@ -2346,10 +2344,10 @@ void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
}
void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
bool smi_operands,
Label* not_numbers,
Label* gc_required) {
void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
bool smi_operands,
Label* not_numbers,
Label* gc_required) {
Register left = a1;
Register right = a0;
Register scratch1 = t3;
@ -2562,7 +2560,8 @@ void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
// generated. If the result is not a smi and heap number allocation is not
// requested the code falls through. If number allocation is requested but a
// heap number cannot be allocated the code jumps to the lable gc_required.
void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
void BinaryOpStub::GenerateSmiCode(
MacroAssembler* masm,
Label* use_runtime,
Label* gc_required,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
@ -2590,11 +2589,11 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
}
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
Label not_smis, call_runtime;
if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) {
if (result_type_ == BinaryOpIC::UNINITIALIZED ||
result_type_ == BinaryOpIC::SMI) {
// Only allow smi results.
GenerateSmiCode(masm, &call_runtime, NULL, NO_HEAPNUMBER_RESULTS);
} else {
@ -2615,18 +2614,18 @@ void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::STRING);
void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::STRING);
// Try to add arguments as strings, otherwise, transition to the generic
// TRBinaryOpIC type.
// BinaryOpIC type.
GenerateAddStrings(masm);
GenerateTypeTransition(masm);
}
void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
Label call_runtime;
ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
ASSERT(op_ == Token::ADD);
// If both arguments are strings, call the string add stub.
// Otherwise, do a transition.
@ -2654,8 +2653,8 @@ void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::INT32);
void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::INT32);
Register left = a1;
Register right = a0;
@ -2764,7 +2763,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
__ srl(scratch2, scratch2, kFCSRFlagShift);
__ And(scratch2, scratch2, kFCSRFlagMask);
if (result_type_ <= TRBinaryOpIC::INT32) {
if (result_type_ <= BinaryOpIC::INT32) {
// If scratch2 != 0, result does not fit in a 32-bit integer.
__ Branch(&transition, ne, scratch2, Operand(zero_reg));
}
@ -2789,8 +2788,8 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// DIV just falls through to allocating a heap number.
}
if (result_type_ >= (op_ == Token::DIV) ? TRBinaryOpIC::HEAP_NUMBER
: TRBinaryOpIC::INT32) {
if (result_type_ >= (op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
: BinaryOpIC::INT32) {
__ bind(&return_heap_number);
// We are using FPU registers so s0 is available.
heap_number_result = s0;
@ -2898,14 +2897,14 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// The non FPU code does not support this special case, so jump to
// runtime if we don't support it.
if (CpuFeatures::IsSupported(FPU)) {
__ Branch((result_type_ <= TRBinaryOpIC::INT32)
__ Branch((result_type_ <= BinaryOpIC::INT32)
? &transition
: &return_heap_number,
lt,
a2,
Operand(zero_reg));
} else {
__ Branch((result_type_ <= TRBinaryOpIC::INT32)
__ Branch((result_type_ <= BinaryOpIC::INT32)
? &transition
: &call_runtime,
lt,
@ -2980,7 +2979,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
Label call_runtime;
if (op_ == Token::ADD) {
@ -3013,7 +3012,7 @@ void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
Label call_runtime;
GenerateFPOperation(masm, false, &call_runtime, &call_runtime);
@ -3022,7 +3021,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
Label call_runtime, call_string_add_or_runtime;
GenerateSmiCode(masm, &call_runtime, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
@ -3039,7 +3038,7 @@ void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD);
Label left_not_string, call_runtime;
@ -3070,7 +3069,7 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
GenerateRegisterArgsPush(masm);
switch (op_) {
case Token::ADD:
@ -3112,7 +3111,7 @@ void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
void BinaryOpStub::GenerateHeapResultAllocation(
MacroAssembler* masm,
Register result,
Register heap_number_map,
@ -3146,7 +3145,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
}
void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
__ Push(a1, a0);
}

View File

@ -72,18 +72,18 @@ class ToBooleanStub: public CodeStub {
};
class TypeRecordingUnaryOpStub: public CodeStub {
class UnaryOpStub: public CodeStub {
public:
TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
: op_(op),
mode_(mode),
operand_type_(TRUnaryOpIC::UNINITIALIZED),
operand_type_(UnaryOpIC::UNINITIALIZED),
name_(NULL) {
}
TypeRecordingUnaryOpStub(
UnaryOpStub(
int key,
TRUnaryOpIC::TypeInfo operand_type)
UnaryOpIC::TypeInfo operand_type)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operand_type_(operand_type),
@ -95,7 +95,7 @@ class TypeRecordingUnaryOpStub: public CodeStub {
UnaryOverwriteMode mode_;
// Operand type information determined at runtime.
TRUnaryOpIC::TypeInfo operand_type_;
UnaryOpIC::TypeInfo operand_type_;
char* name_;
@ -103,20 +103,20 @@ class TypeRecordingUnaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingUnaryOpStub %d (op %s), "
PrintF("UnaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
}
#endif
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
Major MajorKey() { return TypeRecordingUnaryOp; }
Major MajorKey() { return UnaryOp; }
int MinorKey() {
return ModeBits::encode(mode_)
| OpBits::encode(op_)
@ -146,34 +146,34 @@ class TypeRecordingUnaryOpStub: public CodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRUnaryOpIC::ToState(operand_type_);
return UnaryOpIC::ToState(operand_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_unary_op_type(operand_type_);
code->set_unary_op_type(operand_type_);
}
};
class TypeRecordingBinaryOpStub: public CodeStub {
class BinaryOpStub: public CodeStub {
public:
TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
BinaryOpStub(Token::Value op, OverwriteMode mode)
: op_(op),
mode_(mode),
operands_type_(TRBinaryOpIC::UNINITIALIZED),
result_type_(TRBinaryOpIC::UNINITIALIZED),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
use_fpu_ = CpuFeatures::IsSupported(FPU);
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
TypeRecordingBinaryOpStub(
BinaryOpStub(
int key,
TRBinaryOpIC::TypeInfo operands_type,
TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
BinaryOpIC::TypeInfo operands_type,
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
use_fpu_(FPUBits::decode(key)),
@ -192,8 +192,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
bool use_fpu_;
// Operand type information determined at runtime.
TRBinaryOpIC::TypeInfo operands_type_;
TRBinaryOpIC::TypeInfo result_type_;
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
@ -201,12 +201,12 @@ class TypeRecordingBinaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingBinaryOpStub %d (op %s), "
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
}
#endif
@ -214,10 +214,10 @@ class TypeRecordingBinaryOpStub: public CodeStub {
class ModeBits: public BitField<OverwriteMode, 0, 2> {};
class OpBits: public BitField<Token::Value, 2, 7> {};
class FPUBits: public BitField<bool, 9, 1> {};
class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {};
class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
Major MajorKey() { return TypeRecordingBinaryOp; }
Major MajorKey() { return BinaryOp; }
int MinorKey() {
return OpBits::encode(op_)
| ModeBits::encode(mode_)
@ -260,15 +260,15 @@ class TypeRecordingBinaryOpStub: public CodeStub {
void GenerateTypeTransition(MacroAssembler* masm);
void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRBinaryOpIC::ToState(operands_type_);
return BinaryOpIC::ToState(operands_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_binary_op_type(operands_type_);
code->set_type_recording_binary_op_result_type(result_type_);
code->set_binary_op_type(operands_type_);
code->set_binary_op_result_type(result_type_);
}
friend class CodeGenerator;

View File

@ -1723,14 +1723,14 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done);
__ bind(&smi_case);
// Smi case. This code works the same way as the smi-smi case in the type
// recording binary operation stub, see
// TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments.
// BinaryOpStub::GenerateSmiSmiOperation for comments.
switch (op) {
case Token::SAR:
__ Branch(&stub_call);
@ -1804,7 +1804,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) {
__ mov(a0, result_register());
__ pop(a1);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), NULL, expr->id());
context()->Plug(v0);
}
@ -3807,8 +3807,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
UnaryOverwriteMode overwrite =
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
TypeRecordingUnaryOpStub stub(expr->op(), overwrite);
// TypeRecordingGenericUnaryOpStub expects the argument to be in a0.
UnaryOpStub stub(expr->op(), overwrite);
// GenericUnaryOpStub expects the argument to be in a0.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
__ mov(a0, result_register());
@ -3929,7 +3929,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE);
BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
__ bind(&done);

View File

@ -2619,7 +2619,8 @@ int Code::arguments_count() {
int Code::major_key() {
ASSERT(kind() == STUB ||
kind() == TYPE_RECORDING_BINARY_OP_IC ||
kind() == UNARY_OP_IC ||
kind() == BINARY_OP_IC ||
kind() == COMPARE_IC);
return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
}
@ -2627,8 +2628,8 @@ int Code::major_key() {
void Code::set_major_key(int major) {
ASSERT(kind() == STUB ||
kind() == TYPE_RECORDING_UNARY_OP_IC ||
kind() == TYPE_RECORDING_BINARY_OP_IC ||
kind() == UNARY_OP_IC ||
kind() == BINARY_OP_IC ||
kind() == COMPARE_IC);
ASSERT(0 <= major && major < 256);
WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
@ -2736,38 +2737,38 @@ void Code::set_external_array_type(ExternalArrayType value) {
}
byte Code::type_recording_unary_op_type() {
ASSERT(is_type_recording_unary_op_stub());
byte Code::unary_op_type() {
ASSERT(is_unary_op_stub());
return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
}
void Code::set_type_recording_unary_op_type(byte value) {
ASSERT(is_type_recording_unary_op_stub());
void Code::set_unary_op_type(byte value) {
ASSERT(is_unary_op_stub());
WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
}
byte Code::type_recording_binary_op_type() {
ASSERT(is_type_recording_binary_op_stub());
byte Code::binary_op_type() {
ASSERT(is_binary_op_stub());
return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
}
void Code::set_type_recording_binary_op_type(byte value) {
ASSERT(is_type_recording_binary_op_stub());
void Code::set_binary_op_type(byte value) {
ASSERT(is_binary_op_stub());
WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
}
byte Code::type_recording_binary_op_result_type() {
ASSERT(is_type_recording_binary_op_stub());
byte Code::binary_op_result_type() {
ASSERT(is_binary_op_stub());
return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
}
void Code::set_type_recording_binary_op_result_type(byte value) {
ASSERT(is_type_recording_binary_op_stub());
void Code::set_binary_op_result_type(byte value) {
ASSERT(is_binary_op_stub());
WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
}

View File

@ -6591,8 +6591,8 @@ const char* Code::Kind2String(Kind kind) {
case KEYED_STORE_IC: return "KEYED_STORE_IC";
case CALL_IC: return "CALL_IC";
case KEYED_CALL_IC: return "KEYED_CALL_IC";
case TYPE_RECORDING_UNARY_OP_IC: return "TYPE_RECORDING_UNARY_OP_IC";
case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC";
case UNARY_OP_IC: return "UNARY_OP_IC";
case BINARY_OP_IC: return "BINARY_OP_IC";
case COMPARE_IC: return "COMPARE_IC";
}
UNREACHABLE();

View File

@ -3306,8 +3306,8 @@ class Code: public HeapObject {
KEYED_CALL_IC,
STORE_IC,
KEYED_STORE_IC,
TYPE_RECORDING_UNARY_OP_IC,
TYPE_RECORDING_BINARY_OP_IC,
UNARY_OP_IC,
BINARY_OP_IC,
COMPARE_IC,
// No more than 16 kinds. The value currently encoded in four bits in
// Flags.
@ -3381,11 +3381,11 @@ class Code: public HeapObject {
inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
inline bool is_call_stub() { return kind() == CALL_IC; }
inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; }
inline bool is_type_recording_unary_op_stub() {
return kind() == TYPE_RECORDING_UNARY_OP_IC;
inline bool is_unary_op_stub() {
return kind() == UNARY_OP_IC;
}
inline bool is_type_recording_binary_op_stub() {
return kind() == TYPE_RECORDING_BINARY_OP_IC;
inline bool is_binary_op_stub() {
return kind() == BINARY_OP_IC;
}
inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
@ -3435,15 +3435,15 @@ class Code: public HeapObject {
inline ExternalArrayType external_array_type();
inline void set_external_array_type(ExternalArrayType value);
// [type-recording unary op type]: For all TYPE_RECORDING_UNARY_OP_IC.
inline byte type_recording_unary_op_type();
inline void set_type_recording_unary_op_type(byte value);
// [type-recording unary op type]: For all UNARY_OP_IC.
inline byte unary_op_type();
inline void set_unary_op_type(byte value);
// [type-recording binary op type]: For all TYPE_RECORDING_BINARY_OP_IC.
inline byte type_recording_binary_op_type();
inline void set_type_recording_binary_op_type(byte value);
inline byte type_recording_binary_op_result_type();
inline void set_type_recording_binary_op_result_type(byte value);
inline byte binary_op_type();
inline void set_binary_op_type(byte value);
inline byte binary_op_result_type();
inline void set_binary_op_result_type(byte value);
// [compare state]: For kind compare IC stubs, tells what state the
// stub is in.

View File

@ -1568,8 +1568,8 @@ static void ReportCodeKindStatistics() {
CASE(KEYED_STORE_IC);
CASE(CALL_IC);
CASE(KEYED_CALL_IC);
CASE(TYPE_RECORDING_UNARY_OP_IC);
CASE(TYPE_RECORDING_BINARY_OP_IC);
CASE(UNARY_OP_IC);
CASE(BINARY_OP_IC);
CASE(COMPARE_IC);
}
}

View File

@ -258,13 +258,13 @@ TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
ASSERT(code->is_type_recording_unary_op_stub());
TRUnaryOpIC::TypeInfo type = static_cast<TRUnaryOpIC::TypeInfo>(
code->type_recording_unary_op_type());
ASSERT(code->is_unary_op_stub());
UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>(
code->unary_op_type());
switch (type) {
case TRUnaryOpIC::SMI:
case UnaryOpIC::SMI:
return TypeInfo::Smi();
case TRUnaryOpIC::HEAP_NUMBER:
case UnaryOpIC::HEAP_NUMBER:
return TypeInfo::Double();
default:
return unknown;
@ -277,41 +277,41 @@ TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
if (code->is_type_recording_binary_op_stub()) {
TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
code->type_recording_binary_op_type());
TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>(
code->type_recording_binary_op_result_type());
if (code->is_binary_op_stub()) {
BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
code->binary_op_type());
BinaryOpIC::TypeInfo result_type = static_cast<BinaryOpIC::TypeInfo>(
code->binary_op_result_type());
switch (type) {
case TRBinaryOpIC::UNINITIALIZED:
case BinaryOpIC::UNINITIALIZED:
// Uninitialized means never executed.
// TODO(fschneider): Introduce a separate value for never-executed ICs
return unknown;
case TRBinaryOpIC::SMI:
case BinaryOpIC::SMI:
switch (result_type) {
case TRBinaryOpIC::UNINITIALIZED:
case TRBinaryOpIC::SMI:
case BinaryOpIC::UNINITIALIZED:
case BinaryOpIC::SMI:
return TypeInfo::Smi();
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
return TypeInfo::Integer32();
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
return TypeInfo::Double();
default:
return unknown;
}
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
if (expr->op() == Token::DIV ||
result_type == TRBinaryOpIC::HEAP_NUMBER) {
result_type == BinaryOpIC::HEAP_NUMBER) {
return TypeInfo::Double();
}
return TypeInfo::Integer32();
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
return TypeInfo::Double();
case TRBinaryOpIC::BOTH_STRING:
case BinaryOpIC::BOTH_STRING:
return TypeInfo::String();
case TRBinaryOpIC::STRING:
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::STRING:
case BinaryOpIC::GENERIC:
return unknown;
default:
return unknown;
@ -353,21 +353,21 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
TypeInfo unknown = TypeInfo::Unknown();
if (!object->IsCode()) return unknown;
Handle<Code> code = Handle<Code>::cast(object);
if (!code->is_type_recording_binary_op_stub()) return unknown;
if (!code->is_binary_op_stub()) return unknown;
TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
code->type_recording_binary_op_type());
BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
code->binary_op_type());
switch (type) {
case TRBinaryOpIC::UNINITIALIZED:
case TRBinaryOpIC::SMI:
case BinaryOpIC::UNINITIALIZED:
case BinaryOpIC::SMI:
return TypeInfo::Smi();
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
return TypeInfo::Integer32();
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
return TypeInfo::Double();
case TRBinaryOpIC::BOTH_STRING:
case TRBinaryOpIC::STRING:
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::BOTH_STRING:
case BinaryOpIC::STRING:
case BinaryOpIC::GENERIC:
return unknown;
default:
return unknown;
@ -441,8 +441,8 @@ void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
InlineCacheState state = target->ic_state();
Code::Kind kind = target->kind();
if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
kind == Code::TYPE_RECORDING_UNARY_OP_IC ||
if (kind == Code::BINARY_OP_IC ||
kind == Code::UNARY_OP_IC ||
kind == Code::COMPARE_IC) {
SetInfo(id, target);
} else if (state == MONOMORPHIC) {
@ -484,9 +484,9 @@ void TypeFeedbackOracle::CollectIds(Code* code,
if (target->is_inline_cache_stub()) {
InlineCacheState state = target->ic_state();
Code::Kind kind = target->kind();
if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
if (target->type_recording_binary_op_type() ==
TRBinaryOpIC::GENERIC) {
if (kind == Code::BINARY_OP_IC) {
if (target->binary_op_type() ==
BinaryOpIC::GENERIC) {
continue;
}
} else if (kind == Code::COMPARE_IC) {

View File

@ -406,32 +406,31 @@ void IntegerConvert(MacroAssembler* masm,
}
Handle<Code> GetTypeRecordingUnaryOpStub(int key,
TRUnaryOpIC::TypeInfo type_info) {
TypeRecordingUnaryOpStub stub(key, type_info);
Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
UnaryOpStub stub(key, type_info);
return stub.GetCode();
}
void TypeRecordingUnaryOpStub::Generate(MacroAssembler* masm) {
void UnaryOpStub::Generate(MacroAssembler* masm) {
switch (operand_type_) {
case TRUnaryOpIC::UNINITIALIZED:
case UnaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRUnaryOpIC::SMI:
case UnaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRUnaryOpIC::HEAP_NUMBER:
case UnaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRUnaryOpIC::GENERIC:
case UnaryOpIC::GENERIC:
GenerateGenericStub(masm);
break;
}
}
void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ pop(rcx); // Save return address.
__ push(rax);
// Left and right arguments are now on top.
@ -446,7 +445,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingUnaryOp_Patch),
ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
masm->isolate()),
4,
1);
@ -454,7 +453,7 @@ void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateSmiStubSub(masm);
@ -468,7 +467,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
Label slow;
GenerateSmiCodeSub(masm, &slow, &slow, Label::kNear, Label::kNear);
__ bind(&slow);
@ -476,7 +475,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
Label non_smi;
GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
__ bind(&non_smi);
@ -484,11 +483,11 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow,
Label::Distance non_smi_near,
Label::Distance slow_near) {
void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* slow,
Label::Distance non_smi_near,
Label::Distance slow_near) {
Label done;
__ JumpIfNotSmi(rax, non_smi, non_smi_near);
__ SmiNeg(rax, rax, &done, Label::kNear);
@ -498,10 +497,9 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(
MacroAssembler* masm,
Label* non_smi,
Label::Distance non_smi_near) {
void UnaryOpStub::GenerateSmiCodeBitNot(MacroAssembler* masm,
Label* non_smi,
Label::Distance non_smi_near) {
__ JumpIfNotSmi(rax, non_smi, non_smi_near);
__ SmiNot(rax, rax);
__ ret(0);
@ -509,7 +507,7 @@ void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot(
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateHeapNumberStubSub(masm);
@ -523,7 +521,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear);
__ bind(&non_smi);
@ -535,7 +533,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
void UnaryOpStub::GenerateHeapNumberStubBitNot(
MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
@ -546,8 +544,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Label* slow) {
// Check if the operand is a heap number.
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
@ -587,9 +585,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
}
void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
MacroAssembler* masm,
Label* slow) {
void UnaryOpStub::GenerateHeapNumberCodeBitNot(MacroAssembler* masm,
Label* slow) {
// Check if the operand is a heap number.
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
@ -606,7 +603,7 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot(
// TODO(svenpanne): Use virtual functions instead of switch.
void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
switch (op_) {
case Token::SUB:
GenerateGenericStubSub(masm);
@ -620,7 +617,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow, Label::kNear);
__ bind(&non_smi);
@ -630,7 +627,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
__ bind(&non_smi);
@ -640,8 +637,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
MacroAssembler* masm) {
void UnaryOpStub::GenerateGenericCodeFallback(MacroAssembler* masm) {
// Handle the slow case by jumping to the JavaScript builtin.
__ pop(rcx); // pop return address
__ push(rax);
@ -659,7 +655,7 @@ void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback(
}
const char* TypeRecordingUnaryOpStub::GetName() {
const char* UnaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -673,23 +669,23 @@ const char* TypeRecordingUnaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingUnaryOpStub_%s_%s_%s",
"UnaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
return name_;
}
Handle<Code> GetTypeRecordingBinaryOpStub(int key,
TRBinaryOpIC::TypeInfo type_info,
TRBinaryOpIC::TypeInfo result_type_info) {
TypeRecordingBinaryOpStub stub(key, type_info, result_type_info);
Handle<Code> GetBinaryOpStub(int key,
BinaryOpIC::TypeInfo type_info,
BinaryOpIC::TypeInfo result_type_info) {
BinaryOpStub stub(key, type_info, result_type_info);
return stub.GetCode();
}
void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
__ pop(rcx); // Save return address.
__ push(rdx);
__ push(rax);
@ -705,39 +701,39 @@ void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
__ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
masm->isolate()),
5,
1);
}
void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
void BinaryOpStub::Generate(MacroAssembler* masm) {
switch (operands_type_) {
case TRBinaryOpIC::UNINITIALIZED:
case BinaryOpIC::UNINITIALIZED:
GenerateTypeTransition(masm);
break;
case TRBinaryOpIC::SMI:
case BinaryOpIC::SMI:
GenerateSmiStub(masm);
break;
case TRBinaryOpIC::INT32:
case BinaryOpIC::INT32:
UNREACHABLE();
// The int32 case is identical to the Smi case. We avoid creating this
// ic state on x64.
break;
case TRBinaryOpIC::HEAP_NUMBER:
case BinaryOpIC::HEAP_NUMBER:
GenerateHeapNumberStub(masm);
break;
case TRBinaryOpIC::ODDBALL:
case BinaryOpIC::ODDBALL:
GenerateOddballStub(masm);
break;
case TRBinaryOpIC::BOTH_STRING:
case BinaryOpIC::BOTH_STRING:
GenerateBothStringStub(masm);
break;
case TRBinaryOpIC::STRING:
case BinaryOpIC::STRING:
GenerateStringStub(masm);
break;
case TRBinaryOpIC::GENERIC:
case BinaryOpIC::GENERIC:
GenerateGeneric(masm);
break;
default:
@ -746,7 +742,7 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
}
const char* TypeRecordingBinaryOpStub::GetName() {
const char* BinaryOpStub::GetName() {
if (name_ != NULL) return name_;
const int kMaxNameLength = 100;
name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
@ -762,19 +758,20 @@ const char* TypeRecordingBinaryOpStub::GetName() {
}
OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
"TypeRecordingBinaryOpStub_%s_%s_%s",
"BinaryOpStub_%s_%s_%s",
op_name,
overwrite_name,
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
return name_;
}
void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
void BinaryOpStub::GenerateSmiCode(
MacroAssembler* masm,
Label* slow,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
// Arguments to TypeRecordingBinaryOpStub are in rdx and rax.
// Arguments to BinaryOpStub are in rdx and rax.
Register left = rdx;
Register right = rax;
@ -920,10 +917,9 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
}
void TypeRecordingBinaryOpStub::GenerateFloatingPointCode(
MacroAssembler* masm,
Label* allocation_failure,
Label* non_numeric_failure) {
void BinaryOpStub::GenerateFloatingPointCode(MacroAssembler* masm,
Label* allocation_failure,
Label* non_numeric_failure) {
switch (op_) {
case Token::ADD:
case Token::SUB:
@ -1022,12 +1018,12 @@ void TypeRecordingBinaryOpStub::GenerateFloatingPointCode(
// No fall-through from this generated code.
if (FLAG_debug_code) {
__ Abort("Unexpected fall-through in "
"TypeRecordingBinaryStub::GenerateFloatingPointCode.");
"BinaryStub::GenerateFloatingPointCode.");
}
}
void TypeRecordingBinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) {
void BinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD);
Label left_not_string, call_runtime;
@ -1058,7 +1054,7 @@ void TypeRecordingBinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) {
void BinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) {
GenerateRegisterArgsPush(masm);
switch (op_) {
case Token::ADD:
@ -1100,10 +1096,10 @@ void TypeRecordingBinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
Label call_runtime;
if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) {
if (result_type_ == BinaryOpIC::UNINITIALIZED ||
result_type_ == BinaryOpIC::SMI) {
// Only allow smi results.
GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS);
} else {
@ -1123,19 +1119,19 @@ void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == TRBinaryOpIC::STRING);
void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
ASSERT(operands_type_ == BinaryOpIC::STRING);
ASSERT(op_ == Token::ADD);
GenerateStringAddCode(masm);
// Try to add arguments as strings, otherwise, transition to the generic
// TRBinaryOpIC type.
// BinaryOpIC type.
GenerateTypeTransition(masm);
}
void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
Label call_runtime;
ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
ASSERT(op_ == Token::ADD);
// If both arguments are strings, call the string add stub.
// Otherwise, do a transition.
@ -1163,7 +1159,7 @@ void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
Label call_runtime;
if (op_ == Token::ADD) {
@ -1196,7 +1192,7 @@ void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
Label gc_required, not_number;
GenerateFloatingPointCode(masm, &gc_required, &not_number);
@ -1208,7 +1204,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
Label call_runtime, call_string_add_or_runtime;
GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
@ -1225,9 +1221,8 @@ void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
}
void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
MacroAssembler* masm,
Label* alloc_failure) {
void BinaryOpStub::GenerateHeapResultAllocation(MacroAssembler* masm,
Label* alloc_failure) {
Label skip_allocation;
OverwriteMode mode = mode_;
switch (mode) {
@ -1265,7 +1260,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
}
void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
__ pop(rcx);
__ push(rdx);
__ push(rax);

View File

@ -71,18 +71,18 @@ class ToBooleanStub: public CodeStub {
};
class TypeRecordingUnaryOpStub: public CodeStub {
class UnaryOpStub: public CodeStub {
public:
TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
: op_(op),
mode_(mode),
operand_type_(TRUnaryOpIC::UNINITIALIZED),
operand_type_(UnaryOpIC::UNINITIALIZED),
name_(NULL) {
}
TypeRecordingUnaryOpStub(
UnaryOpStub(
int key,
TRUnaryOpIC::TypeInfo operand_type)
UnaryOpIC::TypeInfo operand_type)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operand_type_(operand_type),
@ -94,7 +94,7 @@ class TypeRecordingUnaryOpStub: public CodeStub {
UnaryOverwriteMode mode_;
// Operand type information determined at runtime.
TRUnaryOpIC::TypeInfo operand_type_;
UnaryOpIC::TypeInfo operand_type_;
char* name_;
@ -102,20 +102,20 @@ class TypeRecordingUnaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingUnaryOpStub %d (op %s), "
PrintF("UnaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRUnaryOpIC::GetName(operand_type_));
UnaryOpIC::GetName(operand_type_));
}
#endif
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
class OpBits: public BitField<Token::Value, 1, 7> {};
class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
Major MajorKey() { return TypeRecordingUnaryOp; }
Major MajorKey() { return UnaryOp; }
int MinorKey() {
return ModeBits::encode(mode_)
| OpBits::encode(op_)
@ -151,33 +151,33 @@ class TypeRecordingUnaryOpStub: public CodeStub {
void GenerateGenericStubBitNot(MacroAssembler* masm);
void GenerateGenericCodeFallback(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRUnaryOpIC::ToState(operand_type_);
return UnaryOpIC::ToState(operand_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_unary_op_type(operand_type_);
code->set_unary_op_type(operand_type_);
}
};
class TypeRecordingBinaryOpStub: public CodeStub {
class BinaryOpStub: public CodeStub {
public:
TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
BinaryOpStub(Token::Value op, OverwriteMode mode)
: op_(op),
mode_(mode),
operands_type_(TRBinaryOpIC::UNINITIALIZED),
result_type_(TRBinaryOpIC::UNINITIALIZED),
operands_type_(BinaryOpIC::UNINITIALIZED),
result_type_(BinaryOpIC::UNINITIALIZED),
name_(NULL) {
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
}
TypeRecordingBinaryOpStub(
BinaryOpStub(
int key,
TRBinaryOpIC::TypeInfo operands_type,
TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
BinaryOpIC::TypeInfo operands_type,
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
: op_(OpBits::decode(key)),
mode_(ModeBits::decode(key)),
operands_type_(operands_type),
@ -194,8 +194,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
OverwriteMode mode_;
// Operand type information determined at runtime.
TRBinaryOpIC::TypeInfo operands_type_;
TRBinaryOpIC::TypeInfo result_type_;
BinaryOpIC::TypeInfo operands_type_;
BinaryOpIC::TypeInfo result_type_;
char* name_;
@ -203,22 +203,22 @@ class TypeRecordingBinaryOpStub: public CodeStub {
#ifdef DEBUG
void Print() {
PrintF("TypeRecordingBinaryOpStub %d (op %s), "
PrintF("BinaryOpStub %d (op %s), "
"(mode %d, runtime_type_info %s)\n",
MinorKey(),
Token::String(op_),
static_cast<int>(mode_),
TRBinaryOpIC::GetName(operands_type_));
BinaryOpIC::GetName(operands_type_));
}
#endif
// Minor key encoding in 15 bits RRRTTTOOOOOOOMM.
class ModeBits: public BitField<OverwriteMode, 0, 2> {};
class OpBits: public BitField<Token::Value, 2, 7> {};
class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 9, 3> {};
class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 12, 3> {};
class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 9, 3> {};
class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 12, 3> {};
Major MajorKey() { return TypeRecordingBinaryOp; }
Major MajorKey() { return BinaryOp; }
int MinorKey() {
return OpBits::encode(op_)
| ModeBits::encode(mode_)
@ -252,15 +252,15 @@ class TypeRecordingBinaryOpStub: public CodeStub {
void GenerateTypeTransition(MacroAssembler* masm);
void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
virtual InlineCacheState GetICState() {
return TRBinaryOpIC::ToState(operands_type_);
return BinaryOpIC::ToState(operands_type_);
}
virtual void FinishCode(Code* code) {
code->set_type_recording_binary_op_type(operands_type_);
code->set_type_recording_binary_op_result_type(result_type_);
code->set_binary_op_type(operands_type_);
code->set_binary_op_result_type(result_type_);
}
friend class CodeGenerator;

View File

@ -1672,7 +1672,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ movq(rax, rcx);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done, Label::kNear);
@ -1719,7 +1719,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ pop(rdx);
TypeRecordingBinaryOpStub stub(op, mode);
BinaryOpStub stub(op, mode);
// NULL signals no inlined smi code.
EmitCallIC(stub.GetCode(), NULL, expr->id());
context()->Plug(rax);
@ -3727,8 +3727,8 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
UnaryOverwriteMode overwrite =
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
TypeRecordingUnaryOpStub stub(expr->op(), overwrite);
// TypeRecordingUnaryOpStub expects the argument to be in the
UnaryOpStub stub(expr->op(), overwrite);
// UnaryOpStub expects the argument to be in the
// accumulator register rax.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
@ -3856,7 +3856,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetSourcePosition(expr->position());
// Call stub for +1/-1.
TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
if (expr->op() == Token::INC) {
__ Move(rdx, Smi::FromInt(1));
} else {

View File

@ -453,7 +453,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
// Signal that we don't inline smi code before these stubs in the
// optimizing code generator.
if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
if (code->kind() == Code::BINARY_OP_IC ||
code->kind() == Code::COMPARE_IC) {
__ nop();
}
@ -1294,7 +1294,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->InputAt(1)).is(rax));
ASSERT(ToRegister(instr->result()).is(rax));
TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}