Commit 546b99b7 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Refactor smi tagging and untagging on IA-32.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3493 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0553c7fe
...@@ -86,7 +86,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -86,7 +86,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ EnterConstructFrame(); __ EnterConstructFrame();
// Store a smi-tagged arguments count on the stack. // Store a smi-tagged arguments count on the stack.
__ shl(eax, kSmiTagSize); __ SmiTag(eax);
__ push(eax); __ push(eax);
// Push the function to invoke on the stack. // Push the function to invoke on the stack.
...@@ -255,7 +255,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -255,7 +255,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Retrieve smi-tagged arguments count from the stack. // Retrieve smi-tagged arguments count from the stack.
__ mov(eax, Operand(esp, 0)); __ mov(eax, Operand(esp, 0));
__ shr(eax, kSmiTagSize); __ SmiUntag(eax);
// Push the allocated receiver to the stack. We need two copies // Push the allocated receiver to the stack. We need two copies
// because we may have to return the original one and the calling // because we may have to return the original one and the calling
...@@ -440,8 +440,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -440,8 +440,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ EnterInternalFrame(); // preserves eax, ebx, edi __ EnterInternalFrame(); // preserves eax, ebx, edi
// Store the arguments count on the stack (smi tagged). // Store the arguments count on the stack (smi tagged).
ASSERT(kSmiTag == 0); __ SmiTag(eax);
__ shl(eax, kSmiTagSize);
__ push(eax); __ push(eax);
__ push(edi); // save edi across the call __ push(edi); // save edi across the call
...@@ -452,7 +451,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -452,7 +451,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// Get the arguments count and untag it. // Get the arguments count and untag it.
__ pop(eax); __ pop(eax);
__ shr(eax, kSmiTagSize); __ SmiUntag(eax);
__ LeaveInternalFrame(); __ LeaveInternalFrame();
__ jmp(&patch_receiver); __ jmp(&patch_receiver);
...@@ -634,7 +633,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -634,7 +633,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Invoke the function. // Invoke the function.
ParameterCount actual(eax); ParameterCount actual(eax);
__ shr(eax, kSmiTagSize); __ SmiUntag(eax);
__ mov(edi, Operand(ebp, 4 * kPointerSize)); __ mov(edi, Operand(ebp, 4 * kPointerSize));
__ InvokeFunction(edi, actual, CALL_FUNCTION); __ InvokeFunction(edi, actual, CALL_FUNCTION);
...@@ -831,7 +830,7 @@ static void AllocateJSArray(MacroAssembler* masm, ...@@ -831,7 +830,7 @@ static void AllocateJSArray(MacroAssembler* masm,
// elements_array_end: start of next object // elements_array_end: start of next object
// array_size: size of array (smi) // array_size: size of array (smi)
ASSERT(kSmiTag == 0); ASSERT(kSmiTag == 0);
__ shr(array_size, kSmiTagSize); // Convert from smi to value. __ SmiUntag(array_size); // Convert from smi to value.
__ mov(FieldOperand(elements_array, JSObject::kMapOffset), __ mov(FieldOperand(elements_array, JSObject::kMapOffset),
Factory::fixed_array_map()); Factory::fixed_array_map());
Label not_empty_2, fill_array; Label not_empty_2, fill_array;
...@@ -960,7 +959,7 @@ static void ArrayNativeCode(MacroAssembler* masm, ...@@ -960,7 +959,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
// Handle construction of an array from a list of arguments. // Handle construction of an array from a list of arguments.
__ bind(&argc_two_or_more); __ bind(&argc_two_or_more);
ASSERT(kSmiTag == 0); ASSERT(kSmiTag == 0);
__ shl(eax, kSmiTagSize); // Convet argc to a smi. __ SmiTag(eax); // Convet argc to a smi.
// eax: array_size (smi) // eax: array_size (smi)
// edi: constructor // edi: constructor
// esp[0] : argc // esp[0] : argc
......
...@@ -842,9 +842,9 @@ void DeferredInlineBinaryOperation::Generate() { ...@@ -842,9 +842,9 @@ void DeferredInlineBinaryOperation::Generate() {
__ jmp(&load_right); __ jmp(&load_right);
__ bind(&left_smi); __ bind(&left_smi);
__ sar(left_, 1); __ SmiUntag(left_);
__ cvtsi2sd(xmm0, Operand(left_)); __ cvtsi2sd(xmm0, Operand(left_));
__ shl(left_, 1); __ SmiTag(left_);
if (mode_ == OVERWRITE_LEFT) { if (mode_ == OVERWRITE_LEFT) {
Label alloc_failure; Label alloc_failure;
__ push(left_); __ push(left_);
...@@ -870,9 +870,9 @@ void DeferredInlineBinaryOperation::Generate() { ...@@ -870,9 +870,9 @@ void DeferredInlineBinaryOperation::Generate() {
__ jmp(&do_op); __ jmp(&do_op);
__ bind(&right_smi); __ bind(&right_smi);
__ sar(right_, 1); __ SmiUntag(right_);
__ cvtsi2sd(xmm1, Operand(right_)); __ cvtsi2sd(xmm1, Operand(right_));
__ shl(right_, 1); __ SmiTag(right_);
if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) {
Label alloc_failure; Label alloc_failure;
__ push(left_); __ push(left_);
...@@ -1215,8 +1215,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1215,8 +1215,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
__ test(edx, Operand(edx)); __ test(edx, Operand(edx));
deferred->Branch(not_zero); deferred->Branch(not_zero);
// Tag the result and store it in the quotient register. // Tag the result and store it in the quotient register.
ASSERT(kSmiTagSize == times_2); // adjust code if not the case __ SmiTag(eax);
__ lea(eax, Operand(eax, eax, times_1, kSmiTag));
deferred->BindExit(); deferred->BindExit();
left->Unuse(); left->Unuse();
right->Unuse(); right->Unuse();
...@@ -1276,8 +1275,8 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1276,8 +1275,8 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// Untag both operands. // Untag both operands.
__ mov(answer.reg(), left->reg()); __ mov(answer.reg(), left->reg());
__ sar(answer.reg(), kSmiTagSize); __ SmiUntag(answer.reg());
__ sar(ecx, kSmiTagSize); __ SmiUntag(ecx);
// Perform the operation. // Perform the operation.
switch (op) { switch (op) {
case Token::SAR: case Token::SAR:
...@@ -1299,8 +1298,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1299,8 +1298,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// in a case where it is dropped anyway. // in a case where it is dropped anyway.
__ test(answer.reg(), Immediate(0xc0000000)); __ test(answer.reg(), Immediate(0xc0000000));
__ j(zero, &result_ok); __ j(zero, &result_ok);
ASSERT(kSmiTag == 0); __ SmiTag(ecx);
__ shl(ecx, kSmiTagSize);
deferred->Jump(); deferred->Jump();
__ bind(&result_ok); __ bind(&result_ok);
break; break;
...@@ -1311,8 +1309,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1311,8 +1309,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
// Check that the *signed* result fits in a smi. // Check that the *signed* result fits in a smi.
__ cmp(answer.reg(), 0xc0000000); __ cmp(answer.reg(), 0xc0000000);
__ j(positive, &result_ok); __ j(positive, &result_ok);
ASSERT(kSmiTag == 0); __ SmiTag(ecx);
__ shl(ecx, kSmiTagSize);
deferred->Jump(); deferred->Jump();
__ bind(&result_ok); __ bind(&result_ok);
break; break;
...@@ -1321,9 +1318,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1321,9 +1318,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
UNREACHABLE(); UNREACHABLE();
} }
// Smi-tag the result in answer. // Smi-tag the result in answer.
ASSERT(kSmiTagSize == 1); // Adjust code if not the case. __ SmiTag(answer.reg());
__ lea(answer.reg(),
Operand(answer.reg(), answer.reg(), times_1, kSmiTag));
deferred->BindExit(); deferred->BindExit();
left->Unuse(); left->Unuse();
right->Unuse(); right->Unuse();
...@@ -1373,7 +1368,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, ...@@ -1373,7 +1368,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
ASSERT(kSmiTag == 0); // Adjust code below if not the case. ASSERT(kSmiTag == 0); // Adjust code below if not the case.
// Remove smi tag from the left operand (but keep sign). // Remove smi tag from the left operand (but keep sign).
// Left-hand operand has been copied into answer. // Left-hand operand has been copied into answer.
__ sar(answer.reg(), kSmiTagSize); __ SmiUntag(answer.reg());
// Do multiplication of smis, leaving result in answer. // Do multiplication of smis, leaving result in answer.
__ imul(answer.reg(), Operand(right->reg())); __ imul(answer.reg(), Operand(right->reg()));
// Go slow on overflows. // Go slow on overflows.
...@@ -1720,7 +1715,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -1720,7 +1715,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
__ test(operand->reg(), Immediate(kSmiTagMask)); __ test(operand->reg(), Immediate(kSmiTagMask));
deferred->Branch(not_zero); deferred->Branch(not_zero);
__ mov(answer.reg(), operand->reg()); __ mov(answer.reg(), operand->reg());
__ sar(answer.reg(), kSmiTagSize); __ SmiUntag(answer.reg());
__ shr(answer.reg(), shift_value); __ shr(answer.reg(), shift_value);
// A negative Smi shifted right two is in the positive Smi range. // A negative Smi shifted right two is in the positive Smi range.
if (shift_value < 2) { if (shift_value < 2) {
...@@ -1728,9 +1723,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -1728,9 +1723,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
deferred->Branch(not_zero); deferred->Branch(not_zero);
} }
operand->Unuse(); operand->Unuse();
ASSERT(kSmiTagSize == times_2); // Adjust the code if not true. __ SmiTag(answer.reg());
__ lea(answer.reg(),
Operand(answer.reg(), answer.reg(), times_1, kSmiTag));
deferred->BindExit(); deferred->BindExit();
frame_->Push(&answer); frame_->Push(&answer);
} }
...@@ -2243,7 +2236,7 @@ void CodeGenerator::CallApplyLazy(Property* apply, ...@@ -2243,7 +2236,7 @@ void CodeGenerator::CallApplyLazy(Property* apply,
__ bind(&adapted); __ bind(&adapted);
static const uint32_t kArgumentsLimit = 1 * KB; static const uint32_t kArgumentsLimit = 1 * KB;
__ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ shr(eax, kSmiTagSize); __ SmiUntag(eax);
__ mov(ecx, Operand(eax)); __ mov(ecx, Operand(eax));
__ cmp(eax, kArgumentsLimit); __ cmp(eax, kArgumentsLimit);
build_args.Branch(above); build_args.Branch(above);
...@@ -3270,7 +3263,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -3270,7 +3263,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
frame_->EmitPush(eax); // <- slot 3 frame_->EmitPush(eax); // <- slot 3
frame_->EmitPush(edx); // <- slot 2 frame_->EmitPush(edx); // <- slot 2
__ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset)); __ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset));
__ shl(eax, kSmiTagSize); __ SmiTag(eax);
frame_->EmitPush(eax); // <- slot 1 frame_->EmitPush(eax); // <- slot 1
frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0 frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0
entry.Jump(); entry.Jump();
...@@ -3282,7 +3275,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -3282,7 +3275,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
// Push the length of the array and the initial index onto the stack. // Push the length of the array and the initial index onto the stack.
__ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
__ shl(eax, kSmiTagSize); __ SmiTag(eax);
frame_->EmitPush(eax); // <- slot 1 frame_->EmitPush(eax); // <- slot 1
frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0 frame_->EmitPush(Immediate(Smi::FromInt(0))); // <- slot 0
...@@ -4447,10 +4440,13 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { ...@@ -4447,10 +4440,13 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
// Clone the boilerplate object. // Clone the boilerplate object.
int length = node->values()->length(); int length = node->values()->length();
Result clone; Result clone;
if (node->depth() == 1 && if (node->depth() == 1) {
length <= FastCloneShallowArrayStub::kMaximumLength) { if (length <= FastCloneShallowArrayStub::kMaximumLength) {
FastCloneShallowArrayStub stub(length); FastCloneShallowArrayStub stub(length);
clone = frame_->CallStub(&stub, 1); clone = frame_->CallStub(&stub, 1);
} else {
clone = frame_->CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
}
} else { } else {
clone = frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); clone = frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
} }
...@@ -5013,8 +5009,7 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { ...@@ -5013,8 +5009,7 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
times_1, times_1,
SeqAsciiString::kHeaderSize)); SeqAsciiString::kHeaderSize));
__ bind(&got_char_code); __ bind(&got_char_code);
ASSERT(kSmiTag == 0); __ SmiTag(temp.reg());
__ shl(temp.reg(), kSmiTagSize);
__ jmp(&end); __ jmp(&end);
// Handle non-flat strings. // Handle non-flat strings.
...@@ -7028,7 +7023,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) { ...@@ -7028,7 +7023,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
// If the smi tag is 0 we can just leave the tag on one operand. // If the smi tag is 0 we can just leave the tag on one operand.
ASSERT(kSmiTag == 0); // adjust code below if not the case ASSERT(kSmiTag == 0); // adjust code below if not the case
// Remove tag from one of the operands (but keep sign). // Remove tag from one of the operands (but keep sign).
__ sar(eax, kSmiTagSize); __ SmiUntag(eax);
// Do multiplication. // Do multiplication.
__ imul(eax, Operand(ebx)); // multiplication of smis; result in eax __ imul(eax, Operand(ebx)); // multiplication of smis; result in eax
// Go slow on overflows. // Go slow on overflows.
...@@ -7052,8 +7047,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) { ...@@ -7052,8 +7047,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
__ test(edx, Operand(edx)); __ test(edx, Operand(edx));
__ j(not_zero, slow); __ j(not_zero, slow);
// Tag the result and store it in register eax. // Tag the result and store it in register eax.
ASSERT(kSmiTagSize == times_2); // adjust code if not the case __ SmiTag(eax);
__ lea(eax, Operand(eax, eax, times_1, kSmiTag));
break; break;
case Token::MOD: case Token::MOD:
...@@ -7112,8 +7106,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) { ...@@ -7112,8 +7106,7 @@ void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
UNREACHABLE(); UNREACHABLE();
} }
// Tag the result and store it in register eax. // Tag the result and store it in register eax.
ASSERT(kSmiTagSize == times_2); // adjust code if not the case __ SmiTag(eax);
__ lea(eax, Operand(eax, eax, times_1, kSmiTag));
break; break;
default: default:
...@@ -7262,8 +7255,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { ...@@ -7262,8 +7255,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ j(negative, &non_smi_result); __ j(negative, &non_smi_result);
} }
// Tag smi result and return. // Tag smi result and return.
ASSERT(kSmiTagSize == times_2); // adjust code if not the case __ SmiTag(eax);
__ lea(eax, Operand(eax, eax, times_1, kSmiTag));
GenerateReturn(masm); GenerateReturn(masm);
// All ops except SHR return a signed int32 that we load in a HeapNumber. // All ops except SHR return a signed int32 that we load in a HeapNumber.
...@@ -7611,14 +7603,14 @@ void FloatingPointHelper::LoadSse2Operands(MacroAssembler* masm, ...@@ -7611,14 +7603,14 @@ void FloatingPointHelper::LoadSse2Operands(MacroAssembler* masm,
__ j(equal, &load_float_eax); __ j(equal, &load_float_eax);
__ jmp(not_numbers); // Argument in eax is not a number. __ jmp(not_numbers); // Argument in eax is not a number.
__ bind(&load_smi_edx); __ bind(&load_smi_edx);
__ sar(edx, 1); // Untag smi before converting to float. __ SmiUntag(edx); // Untag smi before converting to float.
__ cvtsi2sd(xmm0, Operand(edx)); __ cvtsi2sd(xmm0, Operand(edx));
__ shl(edx, 1); // Retag smi for heap number overwriting test. __ SmiTag(edx); // Retag smi for heap number overwriting test.
__ jmp(&load_eax); __ jmp(&load_eax);
__ bind(&load_smi_eax); __ bind(&load_smi_eax);
__ sar(eax, 1); // Untag smi before converting to float. __ SmiUntag(eax); // Untag smi before converting to float.
__ cvtsi2sd(xmm1, Operand(eax)); __ cvtsi2sd(xmm1, Operand(eax));
__ shl(eax, 1); // Retag smi for heap number overwriting test. __ SmiTag(eax); // Retag smi for heap number overwriting test.
__ jmp(&done); __ jmp(&done);
__ bind(&load_float_eax); __ bind(&load_float_eax);
__ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
......
...@@ -142,6 +142,15 @@ class MacroAssembler: public Assembler { ...@@ -142,6 +142,15 @@ class MacroAssembler: public Assembler {
// jcc instructions (je, ja, jae, jb, jbe, je, and jz). // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
void FCmp(); void FCmp();
// Smi tagging support.
void SmiTag(Register reg) {
ASSERT(kSmiTag == 0);
shl(reg, kSmiTagSize);
}
void SmiUntag(Register reg) {
sar(reg, kSmiTagSize);
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Exception handling // Exception handling
......
...@@ -236,7 +236,7 @@ void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, ...@@ -236,7 +236,7 @@ void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
// Load length from the string and convert to a smi. // Load length from the string and convert to a smi.
__ bind(&load_length); __ bind(&load_length);
__ mov(eax, FieldOperand(receiver, String::kLengthOffset)); __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
__ shl(eax, kSmiTagSize); __ SmiTag(eax);
__ ret(0); __ ret(0);
// Check if the object is a JSValue wrapper. // Check if the object is a JSValue wrapper.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment