Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Unified Diff: src/runtime.cc

Issue 225823003: Implement handlified String::Equals and Name::Equals. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: refactored StringToDouble Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/scanner.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 93ec83fba8a445b54d25a1fe45447ec5dc0d784a..14e9a2c70a1ce3150101db77a984543655a82b5e 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -4365,8 +4365,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
- int position =
- Runtime::StringMatch(isolate, sub, pat, start_index);
+ int position = Runtime::StringMatch(isolate, sub, pat, start_index);
return Smi::FromInt(position);
}
@@ -4466,13 +4465,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
- SealHandleScope shs(isolate);
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, str1, 0);
- CONVERT_ARG_CHECKED(String, str2, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
- if (str1 == str2) return Smi::FromInt(0); // Equal.
+ if (str1.is_identical_to(str2)) return Smi::FromInt(0); // Equal.
int str1_length = str1->length();
int str2_length = str2->length();
@@ -4492,21 +4491,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
int d = str1->Get(0) - str2->Get(0);
if (d != 0) return Smi::FromInt(d);
- str1->TryFlatten();
- str2->TryFlatten();
+ str1 = String::Flatten(str1);
+ str2 = String::Flatten(str2);
- ConsStringIteratorOp* op1 =
- isolate->runtime_state()->string_locale_compare_it1();
- ConsStringIteratorOp* op2 =
- isolate->runtime_state()->string_locale_compare_it2();
- // TODO(dcarney) Can do array compares here more efficiently.
- StringCharacterStream stream1(str1, op1);
- StringCharacterStream stream2(str2, op2);
+ DisallowHeapAllocation no_gc;
+ String::FlatContent flat1 = str1->GetFlatContent();
+ String::FlatContent flat2 = str2->GetFlatContent();
for (int i = 0; i < end; i++) {
- uint16_t char1 = stream1.GetNext();
- uint16_t char2 = stream2.GetNext();
- if (char1 != char2) return Smi::FromInt(char1 - char2);
+ if (flat1.Get(i) != flat2.Get(i)) {
+ return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
+ }
}
return Smi::FromInt(str1_length - str2_length);
@@ -6073,8 +6068,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
}
// Handle special arguments properties.
- if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
- if (key->Equals(isolate->heap()->callee_string())) {
+ if (String::Equals(isolate->factory()->length_string(), key)) {
+ return Smi::FromInt(n);
+ }
+ if (String::Equals(isolate->factory()->callee_string(), key)) {
JSFunction* function = frame->function();
if (function->shared()->strict_mode() == STRICT) {
return isolate->Throw(*isolate->factory()->NewTypeError(
@@ -6174,17 +6171,18 @@ static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
- SealHandleScope shs(isolate);
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(String, subject, 0);
- subject->TryFlatten();
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ subject = String::Flatten(subject);
// Fast case: short integer or some sorts of junk values.
- int len = subject->length();
if (subject->IsSeqOneByteString()) {
+ int len = subject->length();
if (len == 0) return Smi::FromInt(0);
- uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
+ DisallowHeapAllocation no_gc;
+ uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
bool minus = (data[0] == '-');
int start_pos = (minus ? 1 : 0);
@@ -6192,15 +6190,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
return isolate->heap()->nan_value();
} else if (data[start_pos] > '9') {
// Fast check for a junk value. A valid string may start from a
- // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
- // the 'I' character ('Infinity'). All of that have codes not greater than
- // '9' except 'I' and &nbsp;.
+ // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
+ // or the 'I' character ('Infinity'). All of that have codes not greater
+ // than '9' except 'I' and &nbsp;.
if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
return isolate->heap()->nan_value();
}
} else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
- // The maximal/minimal smi has 10 digits. If the string has less digits we
- // know it will fit into the smi-data type.
+ // The maximal/minimal smi has 10 digits. If the string has less digits
+ // we know it will fit into the smi-data type.
int d = ParseDecimalInteger(data, start_pos, len);
if (minus) {
if (d == 0) return isolate->heap()->minus_zero_value();
@@ -6229,8 +6227,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
// Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
flags |= ALLOW_OCTAL | ALLOW_BINARY;
}
- return isolate->heap()->NumberFromDouble(
- StringToDouble(isolate->unicode_cache(), subject, flags));
+
+ return *isolate->factory()->NewNumber(StringToDouble(
+ isolate->unicode_cache(), *subject, flags));
}
@@ -6304,29 +6303,40 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
- SealHandleScope shs(isolate);
-
- CONVERT_ARG_CHECKED(String, s, 0);
+ HandleScope handle_scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_SMI_ARG_CHECKED(radix, 1);
+ RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
- s->TryFlatten();
+ subject = String::Flatten(subject);
+ double value;
- RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
- double value = StringToInt(isolate->unicode_cache(), s, radix);
- return isolate->heap()->NumberFromDouble(value);
+ { DisallowHeapAllocation no_gc;
+ String::FlatContent flat = subject->GetFlatContent();
+
+ // ECMA-262 section 15.1.2.3, empty string is NaN
+ if (flat.IsAscii()) {
+ value = StringToInt(
+ isolate->unicode_cache(), flat.ToOneByteVector(), radix);
+ } else {
+ value = StringToInt(
+ isolate->unicode_cache(), flat.ToUC16Vector(), radix);
+ }
+ }
+
+ return *isolate->factory()->NewNumber(value);
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
- SealHandleScope shs(isolate);
- CONVERT_ARG_CHECKED(String, str, 0);
+ HandleScope shs(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
- // ECMA-262 section 15.1.2.3, empty string is NaN
- double value = StringToDouble(isolate->unicode_cache(),
- str, ALLOW_TRAILING_JUNK, OS::nan_value());
+ subject = String::Flatten(subject);
+ double value = StringToDouble(
+ isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
- // Create a number object from the value.
- return isolate->heap()->NumberFromDouble(value);
+ return *isolate->factory()->NewNumber(value);
}
@@ -7501,13 +7511,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
- SealHandleScope shs(isolate);
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, x, 0);
- CONVERT_ARG_CHECKED(String, y, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
- bool not_equal = !x->Equals(y);
+ bool not_equal = !String::Equals(x, y);
// This is slightly convoluted because the value that signifies
// equality is 0 and inequality is 1 so we have to negate the result
// from String::Equals.
@@ -7608,27 +7618,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
}
-static Object* StringCharacterStreamCompare(RuntimeState* state,
- String* x,
- String* y) {
- StringCharacterStream stream_x(x, state->string_iterator_compare_x());
- StringCharacterStream stream_y(y, state->string_iterator_compare_y());
- while (stream_x.HasMore() && stream_y.HasMore()) {
- int d = stream_x.GetNext() - stream_y.GetNext();
- if (d < 0) return Smi::FromInt(LESS);
- else if (d > 0) return Smi::FromInt(GREATER);
+RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCompare) {
+ HandleScope handle_scope(isolate);
+ ASSERT(args.length() == 2);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+
+ isolate->counters()->string_compare_runtime()->Increment();
+
+ // A few fast case tests before we flatten.
+ if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
+ if (y->length() == 0) {
+ if (x->length() == 0) return Smi::FromInt(EQUAL);
+ return Smi::FromInt(GREATER);
+ } else if (x->length() == 0) {
+ return Smi::FromInt(LESS);
}
- // x is (non-trivial) prefix of y:
- if (stream_y.HasMore()) return Smi::FromInt(LESS);
- // y is prefix of x:
- return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
-}
+ int d = x->Get(0) - y->Get(0);
+ if (d < 0) return Smi::FromInt(LESS);
+ else if (d > 0) return Smi::FromInt(GREATER);
+ // Slow case.
+ x = String::Flatten(x);
+ y = String::Flatten(y);
-static Object* FlatStringCompare(String* x, String* y) {
- ASSERT(x->IsFlat());
- ASSERT(y->IsFlat());
+ DisallowHeapAllocation no_gc;
Object* equal_prefix_result = Smi::FromInt(EQUAL);
int prefix_length = x->length();
if (y->length() < prefix_length) {
@@ -7638,7 +7654,6 @@ static Object* FlatStringCompare(String* x, String* y) {
equal_prefix_result = Smi::FromInt(LESS);
}
int r;
- DisallowHeapAllocation no_gc;
String::FlatContent x_content = x->GetFlatContent();
String::FlatContent y_content = y->GetFlatContent();
if (x_content.IsAscii()) {
@@ -7666,47 +7681,10 @@ static Object* FlatStringCompare(String* x, String* y) {
} else {
result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
}
- ASSERT(result ==
- StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y));
return result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCompare) {
- HandleScope shs(isolate);
- ASSERT(args.length() == 2);
-
- CONVERT_ARG_CHECKED(String, x, 0);
- CONVERT_ARG_CHECKED(String, y, 1);
-
- isolate->counters()->string_compare_runtime()->Increment();
-
- // A few fast case tests before we flatten.
- if (x == y) return Smi::FromInt(EQUAL);
- if (y->length() == 0) {
- if (x->length() == 0) return Smi::FromInt(EQUAL);
- return Smi::FromInt(GREATER);
- } else if (x->length() == 0) {
- return Smi::FromInt(LESS);
- }
-
- int d = x->Get(0) - y->Get(0);
- if (d < 0) return Smi::FromInt(LESS);
- else if (d > 0) return Smi::FromInt(GREATER);
-
- Object* obj;
- { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
-
- return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
- : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
-}
-
-
#define RUNTIME_UNARY_MATH(Name, name) \
RUNTIME_FUNCTION(MaybeObject*, Runtime_Math##Name) { \
SealHandleScope shs(isolate); \
@@ -11583,7 +11561,7 @@ static bool SetContextLocalValue(Isolate* isolate,
Handle<Object> new_value) {
for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
Handle<String> next_name(scope_info->ContextLocalName(i));
- if (variable_name->Equals(*next_name)) {
+ if (String::Equals(variable_name, next_name)) {
VariableMode mode;
InitializationFlag init_flag;
int context_index =
@@ -11615,7 +11593,8 @@ static bool SetLocalVariableValue(Isolate* isolate,
// Parameters.
for (int i = 0; i < scope_info->ParameterCount(); ++i) {
- if (scope_info->ParameterName(i)->Equals(*variable_name)) {
+ HandleScope scope(isolate);
+ if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
frame->SetParameterValue(i, *new_value);
// Argument might be shadowed in heap context, don't stop here.
default_result = true;
@@ -11624,7 +11603,8 @@ static bool SetLocalVariableValue(Isolate* isolate,
// Stack locals.
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
- if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
+ HandleScope scope(isolate);
+ if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
frame->SetExpression(i, *new_value);
return true;
}
@@ -11765,7 +11745,7 @@ static bool SetCatchVariableValue(Isolate* isolate,
Handle<Object> new_value) {
ASSERT(context->IsCatchContext());
Handle<String> name(String::cast(context->extension()));
- if (!name->Equals(*variable_name)) {
+ if (!String::Equals(name, variable_name)) {
return false;
}
context->set(Context::THROWN_OBJECT_INDEX, *new_value);
« no previous file with comments | « src/parser.cc ('k') | src/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698