Author: [email protected]
Date: Wed Feb 18 01:17:22 2009
New Revision: 1294
Modified:
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/codegen-ia32.h
branches/experimental/toiger/src/register-allocator-ia32.cc
branches/experimental/toiger/src/virtual-frame-ia32.cc
Log:
Change compiler to safely write unsafe smis when they are spilled from
the frame, not when they are pushed onto frame. Also fixes unrelated
flaw in virtual-frame.cc.
Review URL: http://codereview.chromium.org/21392
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Wed Feb 18 01:17:22
2009
@@ -1317,7 +1317,13 @@
is_smi.Bind(&left_side, &right_side);
left_side.ToRegister();
// Test smi equality and comparison by signed int comparison.
+ if (IsUnsafeSmi(right_side.handle())) {
+ right_side.ToRegister();
+ ASSERT(right_side.is_valid());
+ __ cmp(left_side.reg(), Operand(right_side.reg()));
+ } else {
__ cmp(Operand(left_side.reg()), Immediate(right_side.handle()));
+ }
left_side.Unuse();
right_side.Unuse();
dest->Split(cc);
@@ -3045,18 +3051,23 @@
void CodeGenerator::VisitLiteral(Literal* node) {
Comment cmnt(masm_, "[ Literal");
- if (node->handle()->IsSmi() && !IsInlineSmi(node)) {
- // To prevent long attacker-controlled byte sequences in code, larger
- // Smis are loaded in two steps via a temporary register.
- Result temp = allocator_->Allocate();
- ASSERT(temp.is_valid());
- int bits = reinterpret_cast<int>(*node->handle());
- __ Set(temp.reg(), Immediate(bits & 0x0000FFFF));
- __ xor_(temp.reg(), bits & 0xFFFF0000);
- frame_->Push(&temp);
- } else {
frame_->Push(node->handle());
}
+
+
+void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) {
+ ASSERT(target.is_valid());
+ ASSERT(value->IsSmi());
+ int bits = reinterpret_cast<int>(*value);
+ __ Set(target, Immediate(bits & 0x0000FFFF));
+ __ xor_(target, bits & 0xFFFF0000);
+}
+
+
+bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) {
+ if (!value->IsSmi()) return false;
+ int int_value = Smi::cast(*value)->value();
+ return !is_intn(int_value, kMaxSmiInlinedBits);
}
Modified: branches/experimental/toiger/src/codegen-ia32.h
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.h (original)
+++ branches/experimental/toiger/src/codegen-ia32.h Wed Feb 18 01:17:22 2009
@@ -464,9 +464,15 @@
bool strict,
ControlDestination* destination);
- // Inline small integer literals. To prevent long attacker-controlled
byte
- // sequences, we only inline small Smis.
+ // To prevent long attacker-controlled byte sequences, integer constants
+ // from the JavaScript source are loaded in two parts if they are larger
+ // than 16 bits.
static const int kMaxSmiInlinedBits = 16;
+ bool IsUnsafeSmi(Handle<Object> value);
+ // Load an integer constant x into a register target using
+ // at most 16 bits of user-controlled data per assembly operation.
+ void LoadUnsafeSmi(Register target, Handle<Object> value);
+
bool IsInlineSmi(Literal* literal);
void SmiComparison(Condition cc, Handle<Object> value, bool strict);
void SmiOperation(Token::Value op,
@@ -615,6 +621,7 @@
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;
+ friend class Result;
DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
};
Modified: branches/experimental/toiger/src/register-allocator-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/register-allocator-ia32.cc (original)
+++ branches/experimental/toiger/src/register-allocator-ia32.cc Wed Feb 18
01:17:22 2009
@@ -40,7 +40,11 @@
if (is_constant()) {
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
- cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+ if (cgen_->IsUnsafeSmi(handle())) {
+ cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+ } else {
+ cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+ }
// This result becomes a copy of the fresh one.
*this = fresh;
}
@@ -57,7 +61,11 @@
cgen_->masm()->mov(fresh.reg(), reg());
} else {
ASSERT(is_constant());
- cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+ if (cgen_->IsUnsafeSmi(handle())) {
+ cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+ } else {
+ cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+ }
}
*this = fresh;
} else if (is_register() && reg().is(target)) {
Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc Wed Feb 18
01:17:22 2009
@@ -79,7 +79,15 @@
break;
case FrameElement::CONSTANT:
- __ Set(Operand(ebp, fp_relative(index)),
Immediate(element.handle()));
+ if (cgen_->IsUnsafeSmi(element.handle())) {
+ Result temp = cgen_->allocator()->Allocate();
+ ASSERT(temp.is_valid());
+ cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
+ __ mov(Operand(ebp, fp_relative(index)), temp.reg());
+ } else {
+ __ Set(Operand(ebp, fp_relative(index)),
+ Immediate(element.handle()));
+ }
break;
case FrameElement::COPY: {
@@ -117,7 +125,14 @@
break;
case FrameElement::CONSTANT:
- __ push(Immediate(element.handle()));
+ if (cgen_->IsUnsafeSmi(element.handle())) {
+ Result temp = cgen_->allocator()->Allocate();
+ ASSERT(temp.is_valid());
+ cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
+ __ push(temp.reg());
+ } else {
+ __ push(Immediate(element.handle()));
+ }
break;
case FrameElement::COPY: {
@@ -217,7 +232,13 @@
case FrameElement::CONSTANT:
if (!source.is_synced()) {
- __ Set(Operand(ebp, fp_relative(i)),
Immediate(source.handle()));
+ if (cgen_->IsUnsafeSmi(source.handle())) {
+ esi_caches = i;
+ cgen_->LoadUnsafeSmi(esi, source.handle());
+ __ mov(Operand(ebp, fp_relative(i)), esi);
+ } else {
+ __ Set(Operand(ebp, fp_relative(i)),
Immediate(source.handle()));
+ }
}
break;
@@ -335,7 +356,11 @@
break;
case FrameElement::CONSTANT:
- __ Set(target.reg(), Immediate(source.handle()));
+ if (cgen_->IsUnsafeSmi(source.handle())) {
+ cgen_->LoadUnsafeSmi(target.reg(), source.handle());
+ } else {
+ __ Set(target.reg(), Immediate(source.handle()));
+ }
break;
case FrameElement::COPY: {
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---