From: ager@chromium.org Date: Mon, 8 Sep 2008 06:17:38 +0000 (+0000) Subject: Avoid string conversion when comparing Smis during sorting. X-Git-Tag: upstream/4.7.83~25442 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0b50dde0e28249f3038f79b3e70f49519e8fb34;p=platform%2Fupstream%2Fv8.git Avoid string conversion when comparing Smis during sorting. Avoid runtime calls for trivial object equality checks. Minor style cleanups. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@185 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/array.js b/src/array.js index 105f41ba2..b532ef14d 100644 --- a/src/array.js +++ b/src/array.js @@ -219,8 +219,9 @@ function SmartMove(array, start_i, del_count, len, num_additional_args) { // %HasLocalProperty would be the appropriate test. We follow // KJS in consulting the prototype. var current = array[j]; - if (!IS_UNDEFINED(current) || j in array) + if (!IS_UNDEFINED(current) || j in array) { new_array[j] = current; + } j++; } j = start_i + del_count; @@ -230,8 +231,9 @@ function SmartMove(array, start_i, del_count, len, num_additional_args) { // appropriate test. We follow KJS in consulting the // prototype. var current = array[j]; - if (!IS_UNDEFINED(current) || j in array) + if (!IS_UNDEFINED(current) || j in array) { new_array[j - del_count + num_additional_args] = current; + } j++; } } else { @@ -241,16 +243,18 @@ function SmartMove(array, start_i, del_count, len, num_additional_args) { // %HasLocalProperty would be the appropriate test. We follow // KJS in consulting the prototype. var current = array[key]; - if (!IS_UNDEFINED(current) || key in array) + if (!IS_UNDEFINED(current) || key in array) { new_array[key] = current; + } } else if (key >= start_i + del_count) { // ECMA-262 15.4.4.12 lines 24 and 41. The spec could also // be interpreted such that %HasLocalProperty would be the // appropriate test. We follow KJS in consulting the // prototype. var current = array[key]; - if (!IS_UNDEFINED(current) || key in array) + if (!IS_UNDEFINED(current) || key in array) { new_array[key - del_count + num_additional_args] = current; + } } } } @@ -658,6 +662,9 @@ function ArraySort(comparefn) { if (IS_FUNCTION(comparefn)) { return comparefn.call(null, x, y); } + if (%_IsSmi(x) && %_IsSmi(y)) { + return %SmiLexicographicCompare(x, y); + } x = ToString(x); y = ToString(y); if (x == y) return 0; @@ -677,7 +684,7 @@ function ArraySort(comparefn) { var parent_index = ((child_index + 1) >> 1) - 1; var parent_value = this[parent_index], child_value = this[child_index]; if (Compare(parent_value, child_value) < 0) { - this[parent_index] = child_value; + this[parent_index] = child_value; this[child_index] = parent_value; } else { break; diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index c4d3f3867..2ab308e8a 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -295,6 +295,8 @@ class ArmCodeGenerator: public CodeGenerator { virtual void GenerateSetValueOf(ZoneList* args); virtual void GenerateFastCharCodeAt(ZoneList* args); + + virtual void GenerateObjectEquals(ZoneList* args); }; @@ -3998,6 +4000,19 @@ void ArmCodeGenerator::GenerateArgumentsAccess(ZoneList* args) { } +void ArmCodeGenerator::GenerateObjectEquals(ZoneList* args) { + ASSERT(args->length() == 2); + + // Load the two objects into registers and perform the comparison. + Load(args->at(0)); + Load(args->at(1)); + __ pop(r0); + __ pop(r1); + __ cmp(r0, Operand(r1)); + cc_reg_ = eq; +} + + void ArmCodeGenerator::GenerateShiftDownAndTailCall( ZoneList* args) { // r0 = number of arguments diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index 6d38136be..e181686fd 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -314,6 +314,8 @@ class Ia32CodeGenerator: public CodeGenerator { virtual void GenerateSetValueOf(ZoneList* args); virtual void GenerateFastCharCodeAt(ZoneList* args); + + virtual void GenerateObjectEquals(ZoneList* args); }; @@ -4264,6 +4266,18 @@ void Ia32CodeGenerator::GenerateArgumentsAccess(ZoneList* args) { } +void Ia32CodeGenerator::GenerateObjectEquals(ZoneList* args) { + ASSERT(args->length() == 2); + + // Load the two objects into registers and perform the comparison. + Load(args->at(0)); + Load(args->at(1)); + __ pop(eax); + __ pop(ecx); + __ cmp(eax, Operand(ecx)); + cc_reg_ = equal; +} + void Ia32CodeGenerator::VisitCallRuntime(CallRuntime* node) { if (CheckForInlineRuntimeCall(node)) return; diff --git a/src/codegen.cc b/src/codegen.cc index 14ab511bd..87b4159c2 100644 --- a/src/codegen.cc +++ b/src/codegen.cc @@ -256,7 +256,9 @@ bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { {&v8::internal::CodeGenerator::GenerateSetValueOf, "_SetValueOf"}, {&v8::internal::CodeGenerator::GenerateFastCharCodeAt, - "_FastCharCodeAt"} + "_FastCharCodeAt"}, + {&v8::internal::CodeGenerator::GenerateObjectEquals, + "_ObjectEquals"} }; if (node->name()->length() > 0 && node->name()->Get(0) == '_') { for (unsigned i = 0; diff --git a/src/codegen.h b/src/codegen.h index 9833445c8..e6bc211ff 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -173,6 +173,9 @@ class CodeGenerator: public Visitor { // Fast support for charCodeAt(n). virtual void GenerateFastCharCodeAt(ZoneList* args) = 0; + // Fast support for object equality testing. + virtual void GenerateObjectEquals(ZoneList* args) = 0; + private: bool is_eval_; // Tells whether code is generated for eval. Handle