Version 3.2.0

Fixed a number of crash bugs.

Turned on Crankshaft by default on x64 and ARM.

Improved Crankshaft for x64 and ARM.

Implemented more of EcmaScript 5 strict mode.


git-svn-id: http://v8.googlecode.com/svn/trunk@7077 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 0b345d3..9dcca9e 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -93,8 +93,8 @@
 
 void LCodeGen::Abort(const char* format, ...) {
   if (FLAG_trace_bailout) {
-    SmartPointer<char> debug_name = graph()->debug_name()->ToCString();
-    PrintF("Aborting LCodeGen in @\"%s\": ", *debug_name);
+    SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
+    PrintF("Aborting LCodeGen in @\"%s\": ", *name);
     va_list arguments;
     va_start(arguments, format);
     OS::VPrint(format, arguments);
@@ -1148,35 +1148,36 @@
 
 
 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
+  XMMRegister left = ToDoubleRegister(instr->InputAt(0));
+  XMMRegister right = ToDoubleRegister(instr->InputAt(1));
+  XMMRegister result = ToDoubleRegister(instr->result());
   // Modulo uses a fixed result register.
-  ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
+  ASSERT(instr->op() == Token::MOD || left.is(result));
   switch (instr->op()) {
     case Token::ADD:
-      __ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
+      __ addsd(left, right);
       break;
     case Token::SUB:
-       __ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
+       __ subsd(left, right);
        break;
     case Token::MUL:
-      __ mulsd(ToDoubleRegister(left), ToDoubleRegister(right));
+      __ mulsd(left, right);
       break;
     case Token::DIV:
-      __ divsd(ToDoubleRegister(left), ToDoubleRegister(right));
+      __ divsd(left, right);
       break;
     case Token::MOD: {
       // Pass two doubles as arguments on the stack.
       __ PrepareCallCFunction(4, eax);
-      __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
-      __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
+      __ movdbl(Operand(esp, 0 * kDoubleSize), left);
+      __ movdbl(Operand(esp, 1 * kDoubleSize), right);
       __ CallCFunction(ExternalReference::double_fp_operation(Token::MOD), 4);
 
       // Return value is in st(0) on ia32.
       // Store it into the (fixed) result register.
       __ sub(Operand(esp), Immediate(kDoubleSize));
       __ fstp_d(Operand(esp, 0));
-      __ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0));
+      __ movdbl(result, Operand(esp, 0));
       __ add(Operand(esp), Immediate(kDoubleSize));
       break;
     }
@@ -1653,6 +1654,19 @@
 }
 
 
+void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
+  Register input = ToRegister(instr->InputAt(0));
+  Register result = ToRegister(instr->result());
+
+  if (FLAG_debug_code) {
+    __ AbortIfNotString(input);
+  }
+
+  __ mov(result, FieldOperand(input, String::kHashFieldOffset));
+  __ IndexFromHash(result, result);
+}
+
+
 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register result = ToRegister(instr->result());
@@ -1662,7 +1676,7 @@
   __ test(FieldOperand(input, String::kHashFieldOffset),
           Immediate(String::kContainsCachedArrayIndexMask));
   NearLabel done;
-  __ j(not_zero, &done);
+  __ j(zero, &done);
   __ mov(result, Factory::false_value());
   __ bind(&done);
 }
@@ -1677,7 +1691,7 @@
 
   __ test(FieldOperand(input, String::kHashFieldOffset),
           Immediate(String::kContainsCachedArrayIndexMask));
-  EmitBranch(true_block, false_block, not_equal);
+  EmitBranch(true_block, false_block, equal);
 }
 
 
@@ -1909,8 +1923,6 @@
   __ mov(InstanceofStub::right(), Immediate(instr->function()));
   static const int kAdditionalDelta = 16;
   int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
-  Label before_push_delta;
-  __ bind(&before_push_delta);
   __ mov(temp, Immediate(delta));
   __ StoreToSafepointRegisterSlot(temp, temp);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false);
@@ -2349,7 +2361,7 @@
                                  LInstruction* instr) {
   // Change context if needed.
   bool change_context =
-      (graph()->info()->closure()->context() != function->context()) ||
+      (info()->closure()->context() != function->context()) ||
       scope()->contains_with() ||
       (scope()->num_heap_slots() > 0);
   if (change_context) {
@@ -2368,7 +2380,7 @@
   RecordPosition(pointers->position());
 
   // Invoke function.
-  if (*function == *graph()->info()->closure()) {
+  if (*function == *info()->closure()) {
     __ CallSelf();
   } else {
     __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
@@ -3688,21 +3700,18 @@
                                  Handle<String> type_name) {
   Condition final_branch_condition = no_condition;
   if (type_name->Equals(Heap::number_symbol())) {
-    __ test(input, Immediate(kSmiTagMask));
-    __ j(zero, true_label);
+    __ JumpIfSmi(input, true_label);
     __ cmp(FieldOperand(input, HeapObject::kMapOffset),
            Factory::heap_number_map());
     final_branch_condition = equal;
 
   } else if (type_name->Equals(Heap::string_symbol())) {
-    __ test(input, Immediate(kSmiTagMask));
-    __ j(zero, false_label);
-    __ mov(input, FieldOperand(input, HeapObject::kMapOffset));
+    __ JumpIfSmi(input, false_label);
+    __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
+    __ j(above_equal, false_label);
     __ test_b(FieldOperand(input, Map::kBitFieldOffset),
               1 << Map::kIsUndetectable);
-    __ j(not_zero, false_label);
-    __ CmpInstanceType(input, FIRST_NONSTRING_TYPE);
-    final_branch_condition = below;
+    final_branch_condition = zero;
 
   } else if (type_name->Equals(Heap::boolean_symbol())) {
     __ cmp(input, Factory::true_value());
@@ -3713,8 +3722,7 @@
   } else if (type_name->Equals(Heap::undefined_symbol())) {
     __ cmp(input, Factory::undefined_value());
     __ j(equal, true_label);
-    __ test(input, Immediate(kSmiTagMask));
-    __ j(zero, false_label);
+    __ JumpIfSmi(input, false_label);
     // Check for undetectable objects => true.
     __ mov(input, FieldOperand(input, HeapObject::kMapOffset));
     __ test_b(FieldOperand(input, Map::kBitFieldOffset),
@@ -3722,8 +3730,7 @@
     final_branch_condition = not_zero;
 
   } else if (type_name->Equals(Heap::function_symbol())) {
-    __ test(input, Immediate(kSmiTagMask));
-    __ j(zero, false_label);
+    __ JumpIfSmi(input, false_label);
     __ CmpObjectType(input, JS_FUNCTION_TYPE, input);
     __ j(equal, true_label);
     // Regular expressions => 'function' (they are callable).
@@ -3731,22 +3738,18 @@
     final_branch_condition = equal;
 
   } else if (type_name->Equals(Heap::object_symbol())) {
-    __ test(input, Immediate(kSmiTagMask));
-    __ j(zero, false_label);
+    __ JumpIfSmi(input, false_label);
     __ cmp(input, Factory::null_value());
     __ j(equal, true_label);
     // Regular expressions => 'function', not 'object'.
-    __ CmpObjectType(input, JS_REGEXP_TYPE, input);
-    __ j(equal, false_label);
+    __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
+    __ j(below, false_label);
+    __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
+    __ j(above_equal, false_label);
     // Check for undetectable objects => false.
     __ test_b(FieldOperand(input, Map::kBitFieldOffset),
               1 << Map::kIsUndetectable);
-    __ j(not_zero, false_label);
-    // Check for JS objects => true.
-    __ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE);
-    __ j(below, false_label);
-    __ CmpInstanceType(input, LAST_JS_OBJECT_TYPE);
-    final_branch_condition = below_equal;
+    final_branch_condition = zero;
 
   } else {
     final_branch_condition = not_equal;