Version 3.0.5
Fixed a couple of cast errors for gcc-3.4.3.
Performance improvements in GC and IA32 code generator.
git-svn-id: http://v8.googlecode.com/svn/trunk@6131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 13a1177..5beec0d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -379,7 +379,7 @@
void FullCodeGenerator::AccumulatorValueContext::Plug(
Handle<Object> lit) const {
- __ mov(result_register(), lit);
+ __ Set(result_register(), Immediate(lit));
}
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index d64f528..9569ac8 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -940,7 +940,7 @@
void LCodeGen::DoConstantI(LConstantI* instr) {
ASSERT(instr->result()->IsRegister());
- __ mov(ToRegister(instr->result()), instr->value());
+ __ Set(ToRegister(instr->result()), Immediate(instr->value()));
}
@@ -973,27 +973,21 @@
void LCodeGen::DoConstantT(LConstantT* instr) {
ASSERT(instr->result()->IsRegister());
- __ mov(ToRegister(instr->result()), Immediate(instr->value()));
+ __ Set(ToRegister(instr->result()), Immediate(instr->value()));
}
-void LCodeGen::DoArrayLength(LArrayLength* instr) {
+void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
Register result = ToRegister(instr->result());
+ Register array = ToRegister(instr->input());
+ __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
+}
- if (instr->hydrogen()->value()->IsLoadElements()) {
- // We load the length directly from the elements array.
- Register elements = ToRegister(instr->input());
- __ mov(result, FieldOperand(elements, FixedArray::kLengthOffset));
- } else {
- // Check that the receiver really is an array.
- Register array = ToRegister(instr->input());
- Register temporary = ToRegister(instr->temporary());
- __ CmpObjectType(array, JS_ARRAY_TYPE, temporary);
- DeoptimizeIf(not_equal, instr->environment());
- // Load length directly from the array.
- __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
- }
+void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
+ Register result = ToRegister(instr->result());
+ Register array = ToRegister(instr->input());
+ __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
}
@@ -1837,6 +1831,48 @@
}
+void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
+ Register function = ToRegister(instr->function());
+ Register temp = ToRegister(instr->temporary());
+ Register result = ToRegister(instr->result());
+
+ // Check that the function really is a function.
+ __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
+ DeoptimizeIf(not_equal, instr->environment());
+
+ // Check whether the function has an instance prototype.
+ NearLabel non_instance;
+ __ test_b(FieldOperand(result, Map::kBitFieldOffset),
+ 1 << Map::kHasNonInstancePrototype);
+ __ j(not_zero, &non_instance);
+
+ // Get the prototype or initial map from the function.
+ __ mov(result,
+ FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+ // Check that the function has a prototype or an initial map.
+ __ cmp(Operand(result), Immediate(Factory::the_hole_value()));
+ DeoptimizeIf(equal, instr->environment());
+
+ // If the function does not have an initial map, we're done.
+ NearLabel done;
+ __ CmpObjectType(result, MAP_TYPE, temp);
+ __ j(not_equal, &done);
+
+ // Get the prototype from the initial map.
+ __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
+ __ jmp(&done);
+
+ // Non-instance prototype: Fetch prototype from constructor field
+ // in the function's map.
+ __ bind(&non_instance);
+ __ mov(result, FieldOperand(result, Map::kConstructorOffset));
+
+ // All done.
+ __ bind(&done);
+}
+
+
void LCodeGen::DoLoadElements(LLoadElements* instr) {
ASSERT(instr->result()->Equals(instr->input()));
Register reg = ToRegister(instr->input());
@@ -2891,9 +2927,6 @@
InstanceType first = instr->hydrogen()->first();
InstanceType last = instr->hydrogen()->last();
- __ test(input, Immediate(kSmiTagMask));
- DeoptimizeIf(zero, instr->environment());
-
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
static_cast<int8_t>(first));
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 3b272d0..8c003a5 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1677,19 +1677,15 @@
}
-LInstruction* LChunkBuilder::DoArrayLength(HArrayLength* instr) {
- LOperand* array = NULL;
- LOperand* temporary = NULL;
+LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
+ LOperand* array = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new LJSArrayLength(array));
+}
- if (instr->value()->IsLoadElements()) {
- array = UseRegisterAtStart(instr->value());
- } else {
- array = UseRegister(instr->value());
- temporary = TempRegister();
- }
- LInstruction* result = new LArrayLength(array, temporary);
- return AssignEnvironment(DefineAsRegister(result));
+LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
+ LOperand* array = UseRegisterAtStart(instr->value());
+ return DefineAsRegister(new LFixedArrayLength(array));
}
@@ -1860,6 +1856,14 @@
}
+LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
+ HLoadFunctionPrototype* instr) {
+ return AssignEnvironment(DefineAsRegister(
+ new LLoadFunctionPrototype(UseRegister(instr->function()),
+ TempRegister())));
+}
+
+
LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
LOperand* input = UseRegisterAtStart(instr->value());
return DefineSameAsFirst(new LLoadElements(input));
@@ -1931,7 +1935,7 @@
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
- bool needs_write_barrier = !instr->value()->type().IsSmi();
+ bool needs_write_barrier = instr->NeedsWriteBarrier();
LOperand* obj = needs_write_barrier
? UseTempRegister(instr->object())
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 3f48e50..94bf8fd 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -104,7 +104,6 @@
// LStoreNamedField
// LStoreNamedGeneric
// LUnaryOperation
-// LArrayLength
// LBitNotI
// LBranch
// LCallNew
@@ -117,6 +116,7 @@
// LClassOfTestAndBranch
// LDeleteProperty
// LDoubleToI
+// LFixedArrayLength
// LHasCachedArrayIndex
// LHasCachedArrayIndexAndBranch
// LHasInstanceType
@@ -128,8 +128,10 @@
// LIsObjectAndBranch
// LIsSmi
// LIsSmiAndBranch
+// LJSArrayLength
// LLoadNamedField
// LLoadNamedGeneric
+// LLoadFunctionPrototype
// LNumberTagD
// LNumberTagI
// LPushArgument
@@ -164,7 +166,6 @@
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayLength) \
V(ArrayLiteral) \
V(BitI) \
V(BitNotI) \
@@ -203,6 +204,7 @@
V(GlobalObject) \
V(GlobalReceiver) \
V(Goto) \
+ V(FixedArrayLength) \
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(Integer32ToDouble) \
@@ -212,6 +214,7 @@
V(IsObjectAndBranch) \
V(IsSmi) \
V(IsSmiAndBranch) \
+ V(JSArrayLength) \
V(HasInstanceType) \
V(HasInstanceTypeAndBranch) \
V(HasCachedArrayIndex) \
@@ -226,6 +229,7 @@
V(LoadKeyedGeneric) \
V(LoadNamedField) \
V(LoadNamedGeneric) \
+ V(LoadFunctionPrototype) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -1146,18 +1150,21 @@
};
-class LArrayLength: public LUnaryOperation {
+class LJSArrayLength: public LUnaryOperation {
public:
- LArrayLength(LOperand* input, LOperand* temporary)
- : LUnaryOperation(input), temporary_(temporary) { }
+ explicit LJSArrayLength(LOperand* input) : LUnaryOperation(input) { }
- LOperand* temporary() const { return temporary_; }
+ DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
+ DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
+};
- DECLARE_CONCRETE_INSTRUCTION(ArrayLength, "array-length")
- DECLARE_HYDROGEN_ACCESSOR(ArrayLength)
- private:
- LOperand* temporary_;
+class LFixedArrayLength: public LUnaryOperation {
+ public:
+ explicit LFixedArrayLength(LOperand* input) : LUnaryOperation(input) { }
+
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
+ DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
};
@@ -1271,6 +1278,22 @@
};
+class LLoadFunctionPrototype: public LUnaryOperation {
+ public:
+ LLoadFunctionPrototype(LOperand* function, LOperand* temporary)
+ : LUnaryOperation(function), temporary_(temporary) { }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
+ DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
+
+ LOperand* function() const { return input(); }
+ LOperand* temporary() const { return temporary_; }
+
+ private:
+ LOperand* temporary_;
+};
+
+
class LLoadElements: public LUnaryOperation {
public:
explicit LLoadElements(LOperand* obj) : LUnaryOperation(obj) { }
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index d435a70..cc2f30d 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -211,9 +211,7 @@
// If input is ASCII, don't even bother calling here if the string to
// match contains a non-ascii character.
if (mode_ == ASCII) {
- for (int i = 0; i < str.length(); i++) {
- ASSERT(str[i] <= String::kMaxAsciiCharCodeU);
- }
+ ASSERT(String::IsAscii(str.start(), str.length()));
}
#endif
int byte_length = str.length() * char_size();