Push version 1.2.7 to trunk.

Improved debugger and profiler support.

Reduced compilation time by improving the handling of deferred code.

Optimized interceptor accesses where the property is on the object on which the interceptors is attached.

Fixed compilation problem on GCC 4.4 by changing the stack alignment to 16 bytes.

Fixed handle creation to follow stric aliasing rules.

Fixed compilation on FreeBSD.

Introduced API for forcing the deletion of a property ignoring interceptors and attributes.


git-svn-id: http://v8.googlecode.com/svn/trunk@2121 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/codegen-arm-inl.h b/src/arm/codegen-arm-inl.h
new file mode 100644
index 0000000..544331a
--- /dev/null
+++ b/src/arm/codegen-arm-inl.h
@@ -0,0 +1,46 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#ifndef V8_ARM_CODEGEN_ARM_INL_H_
+#define V8_ARM_CODEGEN_ARM_INL_H_
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm_)
+
+// Platform-specific inline functions.
+
+void DeferredCode::Jump() { __ jmp(&entry_label_); }
+void DeferredCode::Branch(Condition cc) { __ b(cc, &entry_label_); }
+
+#undef __
+
+} }  // namespace v8::internal
+
+#endif  // V8_ARM_CODEGEN_ARM_INL_H_
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index fe6d945..7428d3b 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -41,6 +41,34 @@
 
 #define __ ACCESS_MASM(masm_)
 
+// -------------------------------------------------------------------------
+// Platform-specific DeferredCode functions.
+
+void DeferredCode::SaveRegisters() {
+  for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
+    int action = registers_[i];
+    if (action == kPush) {
+      __ push(RegisterAllocator::ToRegister(i));
+    } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
+      __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
+    }
+  }
+}
+
+
+void DeferredCode::RestoreRegisters() {
+  // Restore registers in reverse order due to the stack.
+  for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
+    int action = registers_[i];
+    if (action == kPush) {
+      __ pop(RegisterAllocator::ToRegister(i));
+    } else if (action != kIgnore) {
+      action &= ~kSyncedFlag;
+      __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
+    }
+  }
+}
+
 
 // -------------------------------------------------------------------------
 // CodeGenState implementation.
@@ -776,23 +804,14 @@
 };
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
 void DeferredInlineSmiOperation::Generate() {
-  MacroAssembler* masm = cgen()->masm();
-  enter()->Bind();
-  VirtualFrame::SpilledScope spilled_scope;
-
   switch (op_) {
     case Token::ADD: {
+      // Revert optimistic add.
       if (reversed_) {
-        // revert optimistic add
         __ sub(r0, r0, Operand(Smi::FromInt(value_)));
         __ mov(r1, Operand(Smi::FromInt(value_)));
       } else {
-        // revert optimistic add
         __ sub(r1, r0, Operand(Smi::FromInt(value_)));
         __ mov(r0, Operand(Smi::FromInt(value_)));
       }
@@ -800,8 +819,8 @@
     }
 
     case Token::SUB: {
+      // Revert optimistic sub.
       if (reversed_) {
-        // revert optimistic sub
         __ rsb(r0, r0, Operand(Smi::FromInt(value_)));
         __ mov(r1, Operand(Smi::FromInt(value_)));
       } else {
@@ -830,31 +849,22 @@
         __ mov(r1, Operand(r0));
         __ mov(r0, Operand(Smi::FromInt(value_)));
       } else {
-        UNREACHABLE();  // should have been handled in SmiOperation
+        UNREACHABLE();  // Should have been handled in SmiOperation.
       }
       break;
     }
 
     default:
-      // other cases should have been handled before this point.
+      // Other cases should have been handled before this point.
       UNREACHABLE();
       break;
   }
 
-  GenericBinaryOpStub igostub(op_, overwrite_mode_);
-  Result arg0 = cgen()->allocator()->Allocate(r1);
-  ASSERT(arg0.is_valid());
-  Result arg1 = cgen()->allocator()->Allocate(r0);
-  ASSERT(arg1.is_valid());
-  cgen()->frame()->CallStub(&igostub, &arg0, &arg1);
-  exit_.Jump();
+  GenericBinaryOpStub stub(op_, overwrite_mode_);
+  __ CallStub(&stub);
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm_)
-
-
 void CodeGenerator::SmiOperation(Token::Value op,
                                  Handle<Object> value,
                                  bool reversed,
@@ -877,28 +887,28 @@
   switch (op) {
     case Token::ADD: {
       DeferredCode* deferred =
-        new DeferredInlineSmiOperation(op, int_value, reversed, mode);
+          new DeferredInlineSmiOperation(op, int_value, reversed, mode);
 
       __ add(r0, r0, Operand(value), SetCC);
-      deferred->enter()->Branch(vs);
+      deferred->Branch(vs);
       __ tst(r0, Operand(kSmiTagMask));
-      deferred->enter()->Branch(ne);
+      deferred->Branch(ne);
       deferred->BindExit();
       break;
     }
 
     case Token::SUB: {
       DeferredCode* deferred =
-        new DeferredInlineSmiOperation(op, int_value, reversed, mode);
+          new DeferredInlineSmiOperation(op, int_value, reversed, mode);
 
-      if (!reversed) {
-        __ sub(r0, r0, Operand(value), SetCC);
-      } else {
+      if (reversed) {
         __ rsb(r0, r0, Operand(value), SetCC);
+      } else {
+        __ sub(r0, r0, Operand(value), SetCC);
       }
-      deferred->enter()->Branch(vs);
+      deferred->Branch(vs);
       __ tst(r0, Operand(kSmiTagMask));
-      deferred->enter()->Branch(ne);
+      deferred->Branch(ne);
       deferred->BindExit();
       break;
     }
@@ -909,7 +919,7 @@
       DeferredCode* deferred =
         new DeferredInlineSmiOperation(op, int_value, reversed, mode);
       __ tst(r0, Operand(kSmiTagMask));
-      deferred->enter()->Branch(ne);
+      deferred->Branch(ne);
       switch (op) {
         case Token::BIT_OR:  __ orr(r0, r0, Operand(value)); break;
         case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
@@ -934,14 +944,14 @@
         DeferredCode* deferred =
           new DeferredInlineSmiOperation(op, shift_value, false, mode);
         __ tst(r0, Operand(kSmiTagMask));
-        deferred->enter()->Branch(ne);
+        deferred->Branch(ne);
         __ mov(r2, Operand(r0, ASR, kSmiTagSize));  // remove tags
         switch (op) {
           case Token::SHL: {
             __ mov(r2, Operand(r2, LSL, shift_value));
             // check that the *unsigned* result fits in a smi
             __ add(r3, r2, Operand(0x40000000), SetCC);
-            deferred->enter()->Branch(mi);
+            deferred->Branch(mi);
             break;
           }
           case Token::SHR: {
@@ -956,7 +966,7 @@
             // smi tagging these two cases can only happen with shifts
             // by 0 or 1 when handed a valid smi
             __ and_(r3, r2, Operand(0xc0000000), SetCC);
-            deferred->enter()->Branch(ne);
+            deferred->Branch(ne);
             break;
           }
           case Token::SAR: {
@@ -2670,40 +2680,25 @@
 };
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
 void DeferredObjectLiteral::Generate() {
-  MacroAssembler* masm = cgen()->masm();
   // Argument is passed in r1.
-  enter()->Bind();
-  VirtualFrame::SpilledScope spilled_scope;
 
   // If the entry is undefined we call the runtime system to compute
   // the literal.
-
-  VirtualFrame* frame = cgen()->frame();
   // Literal array (0).
-  frame->EmitPush(r1);
+  __ push(r1);
   // Literal index (1).
   __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
-  frame->EmitPush(r0);
+  __ push(r0);
   // Constant properties (2).
   __ mov(r0, Operand(node_->constant_properties()));
-  frame->EmitPush(r0);
-  Result boilerplate =
-      frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
-  __ mov(r2, Operand(boilerplate.reg()));
+  __ push(r0);
+  __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
+  __ mov(r2, Operand(r0));
   // Result is returned in r2.
-  exit_.Jump();
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm_)
-
-
 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
 #ifdef DEBUG
   int original_height = frame_->height();
@@ -2729,7 +2724,7 @@
   // Check whether we need to materialize the object literal boilerplate.
   // If so, jump to the deferred code.
   __ cmp(r2, Operand(Factory::undefined_value()));
-  deferred->enter()->Branch(eq);
+  deferred->Branch(eq);
   deferred->BindExit();
 
   // Push the object literal boilerplate.
@@ -2807,40 +2802,25 @@
 };
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
 void DeferredArrayLiteral::Generate() {
-  MacroAssembler* masm = cgen()->masm();
   // Argument is passed in r1.
-  enter()->Bind();
-  VirtualFrame::SpilledScope spilled_scope;
 
   // If the entry is undefined we call the runtime system to computed
   // the literal.
-
-  VirtualFrame* frame = cgen()->frame();
   // Literal array (0).
-  frame->EmitPush(r1);
+  __ push(r1);
   // Literal index (1).
   __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
-  frame->EmitPush(r0);
+  __ push(r0);
   // Constant properties (2).
   __ mov(r0, Operand(node_->literals()));
-  frame->EmitPush(r0);
-  Result boilerplate =
-      frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
-  __ mov(r2, Operand(boilerplate.reg()));
+  __ push(r0);
+  __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
+  __ mov(r2, Operand(r0));
   // Result is returned in r2.
-  exit_.Jump();
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm_)
-
-
 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
 #ifdef DEBUG
   int original_height = frame_->height();
@@ -2866,7 +2846,7 @@
   // Check whether we need to materialize the object literal boilerplate.
   // If so, jump to the deferred code.
   __ cmp(r2, Operand(Factory::undefined_value()));
-  deferred->enter()->Branch(eq);
+  deferred->Branch(eq);
   deferred->BindExit();
 
   // Push the object literal boilerplate.
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 3eb8269..c09f9e3 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -246,6 +246,7 @@
 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
                                            JSObject* object,
                                            JSObject* holder,
+                                           Smi* lookup_hint,
                                            Register receiver,
                                            Register name,
                                            Register scratch1,
@@ -263,11 +264,13 @@
   __ push(receiver);  // receiver
   __ push(reg);  // holder
   __ push(name);  // name
+  __ mov(scratch1, Operand(lookup_hint));
+  __ push(scratch1);
 
   // Do tail-call to the runtime system.
   ExternalReference load_ic_property =
       ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
-  __ TailCallRuntime(load_ic_property, 3);
+  __ TailCallRuntime(load_ic_property, 4);
 }
 
 
@@ -909,7 +912,15 @@
 
   __ ldr(r0, MemOperand(sp, 0));
 
-  GenerateLoadInterceptor(masm(), object, holder, r0, r2, r3, r1, &miss);
+  GenerateLoadInterceptor(masm(),
+                          object,
+                          holder,
+                          holder->InterceptorPropertyLookupHint(name),
+                          r0,
+                          r2,
+                          r3,
+                          r1,
+                          &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
@@ -1015,7 +1026,15 @@
   __ cmp(r2, Operand(Handle<String>(name)));
   __ b(ne, &miss);
 
-  GenerateLoadInterceptor(masm(), receiver, holder, r0, r2, r3, r1, &miss);
+  GenerateLoadInterceptor(masm(),
+                          receiver,
+                          holder,
+                          Smi::FromInt(JSObject::kLookupInHolder),
+                          r0,
+                          r2,
+                          r3,
+                          r1,
+                          &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
diff --git a/src/arm/virtual-frame-arm.h b/src/arm/virtual-frame-arm.h
index fc202e2..ebebd53 100644
--- a/src/arm/virtual-frame-arm.h
+++ b/src/arm/virtual-frame-arm.h
@@ -525,6 +525,8 @@
 
   bool Equals(VirtualFrame* other);
 
+  // Classes that need raw access to the elements_ array.
+  friend class DeferredCode;
   friend class JumpTarget;
 };