Commit eb656c72 authored by lrn@chromium.org's avatar lrn@chromium.org

Moved subject and index before matches in RegExp lastMatchInfo.

Some minor changes, and removed the new handlescope in the inner loop of replace. Only really affects replaces on extremely long strings.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1524 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 37d7dcd2
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "compilation-cache.h" #include "compilation-cache.h"
#include "debug.h" #include "debug.h"
#include "global-handles.h" #include "global-handles.h"
#include "jsregexp.h"
#include "mark-compact.h" #include "mark-compact.h"
#include "natives.h" #include "natives.h"
#include "scanner.h" #include "scanner.h"
......
...@@ -307,9 +307,10 @@ Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, ...@@ -307,9 +307,10 @@ Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
// that is attached to the global RegExp object. We will be returning // that is attached to the global RegExp object. We will be returning
// an array of these. // an array of these.
Handle<FixedArray> array = Factory::NewFixedArray(kFirstCapture + 2); Handle<FixedArray> array = Factory::NewFixedArray(kFirstCapture + 2);
SetLastCaptureCount(*array, 2);
// Ignore subject and input fields.
SetCapture(*array, 0, value); SetCapture(*array, 0, value);
SetCapture(*array, 1, end); SetCapture(*array, 1, end);
SetLastCaptureCount(*array, 2);
Handle<JSArray> pair = Factory::NewJSArrayWithElements(array); Handle<JSArray> pair = Factory::NewJSArrayWithElements(array);
SetElement(result, match_count, pair); SetElement(result, match_count, pair);
match_count++; match_count++;
...@@ -561,22 +562,22 @@ Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp, ...@@ -561,22 +562,22 @@ Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
// Create an array that looks like the static last_match_info array // Create an array that looks like the static last_match_info array
// that is attached to the global RegExp object. We will be returning // that is attached to the global RegExp object. We will be returning
// an array of these. // an array of these.
Handle<FixedArray> matches_array(JSArray::cast(*matches)->elements()); int match_length = kFirstCapture + number_of_capture_registers;
Handle<JSArray> latest_match = Handle<JSArray> latest_match =
Factory::NewJSArray(kFirstCapture + number_of_capture_registers); Factory::NewJSArray(match_length);
Handle<FixedArray> latest_match_array(latest_match->elements());
AssertNoAllocation no_allocation;
for (int i = 0; i < number_of_capture_registers; i++) { FixedArray* match_array = JSArray::cast(*matches)->elements();
SetCapture(*latest_match_array, i, GetCapture(*matches_array, i)); match_array->CopyTo(0,
} latest_match->elements(),
SetLastCaptureCount(*latest_match_array, number_of_capture_registers); 0,
match_length);
SetElement(result, result_length, latest_match); SetElement(result, result_length, latest_match);
result_length++; result_length++;
previous_index = GetCapture(*matches_array, 1); previous_index = GetCapture(match_array, 1);
if (GetCapture(*matches_array, 0) == previous_index) if (GetCapture(match_array, 0) == previous_index) {
previous_index++; previous_index++;
}
} else { } else {
ASSERT(matches->IsNull()); ASSERT(matches->IsNull());
return result; return result;
...@@ -636,18 +637,15 @@ Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> regexp, ...@@ -636,18 +637,15 @@ Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> regexp,
} }
FixedArray* array = last_match_info->elements(); FixedArray* array = last_match_info->elements();
// Clear previous input/string values to avoid potential memory leak.
SetLastSubject(array, Heap::empty_string());
SetLastInput(array, Heap::empty_string());
ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead); ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
// The captures come in (start, end+1) pairs. // The captures come in (start, end+1) pairs.
for (int i = 0; i < number_of_capture_registers; i += 2) {
SetCapture(array, i, offsets_vector[i]);
SetCapture(array, i + 1, offsets_vector[i + 1]);
}
SetLastCaptureCount(array, number_of_capture_registers); SetLastCaptureCount(array, number_of_capture_registers);
SetLastSubject(array, *original_subject); SetLastSubject(array, *original_subject);
SetLastInput(array, *original_subject); SetLastInput(array, *original_subject);
for (int i = 0; i < number_of_capture_registers; i+=2) {
SetCapture(array, i, offsets_vector[i]);
SetCapture(array, i + 1, offsets_vector[i + 1]);
}
return last_match_info; return last_match_info;
} }
......
...@@ -112,7 +112,7 @@ class RegExpImpl { ...@@ -112,7 +112,7 @@ class RegExpImpl {
static const int kLastCaptureCount = 0; static const int kLastCaptureCount = 0;
static const int kLastSubject = 1; static const int kLastSubject = 1;
static const int kLastInput = 2; static const int kLastInput = 2;
static const int kFirstCapture = 1; static const int kFirstCapture = 3;
static const int kLastMatchOverhead = 3; static const int kLastMatchOverhead = 3;
// Used to access the lastMatchInfo array. // Used to access the lastMatchInfo array.
...@@ -125,13 +125,11 @@ class RegExpImpl { ...@@ -125,13 +125,11 @@ class RegExpImpl {
} }
static void SetLastSubject(FixedArray* array, String* to) { static void SetLastSubject(FixedArray* array, String* to) {
int capture_count = GetLastCaptureCount(array); array->set(kLastSubject, to);
array->set(capture_count + kLastSubject, to);
} }
static void SetLastInput(FixedArray* array, String* to) { static void SetLastInput(FixedArray* array, String* to) {
int capture_count = GetLastCaptureCount(array); array->set(kLastInput, to);
array->set(capture_count + kLastInput, to);
} }
static void SetCapture(FixedArray* array, int index, int to) { static void SetCapture(FixedArray* array, int index, int to) {
......
...@@ -102,7 +102,7 @@ const ORIGINAL_DATE = (global.Date, $Date); ...@@ -102,7 +102,7 @@ const ORIGINAL_DATE = (global.Date, $Date);
# Constants used on an array to implement the properties of the RegExp object. # Constants used on an array to implement the properties of the RegExp object.
const REGEXP_NUMBER_OF_CAPTURES = 0; const REGEXP_NUMBER_OF_CAPTURES = 0;
const REGEXP_FIRST_CAPTURE = 1; const REGEXP_FIRST_CAPTURE = 3;
# We can't put macros in macros so we use constants here. # We can't put macros in macros so we use constants here.
# REGEXP_NUMBER_OF_CAPTURES # REGEXP_NUMBER_OF_CAPTURES
...@@ -111,10 +111,10 @@ macro NUMBER_OF_CAPTURES(array) = ((array)[0]); ...@@ -111,10 +111,10 @@ macro NUMBER_OF_CAPTURES(array) = ((array)[0]);
# Last input and last subject are after the captures so we can omit them on # Last input and last subject are after the captures so we can omit them on
# results returned from global searches. Beware - these evaluate their # results returned from global searches. Beware - these evaluate their
# arguments twice. # arguments twice.
macro LAST_SUBJECT(array) = ((array)[(array)[0] + 1]); macro LAST_SUBJECT(array) = ((array)[1]);
macro LAST_INPUT(array) = ((array)[(array)[0] + 2]); macro LAST_INPUT(array) = ((array)[2]);
# REGEXP_FIRST_CAPTURE # REGEXP_FIRST_CAPTURE
macro CAPTURE(index) = (1 + (index)); macro CAPTURE(index) = (3 + (index));
const CAPTURE0 = 1; const CAPTURE0 = 3;
const CAPTURE1 = 2; const CAPTURE1 = 4;
...@@ -300,7 +300,7 @@ function RegExpGetRightContext() { ...@@ -300,7 +300,7 @@ function RegExpGetRightContext() {
// The properties $1..$9 are the first nine capturing substrings of the last // The properties $1..$9 are the first nine capturing substrings of the last
// successful match, or ''. The function RegExpMakeCaptureGetter will be // successful match, or ''. The function RegExpMakeCaptureGetter will be
// called with indeces from 1 to 9. // called with indices from 1 to 9.
function RegExpMakeCaptureGetter(n) { function RegExpMakeCaptureGetter(n) {
return function() { return function() {
var index = n * 2; var index = n * 2;
...@@ -321,10 +321,10 @@ function RegExpMakeCaptureGetter(n) { ...@@ -321,10 +321,10 @@ function RegExpMakeCaptureGetter(n) {
// the subject string for the last successful match. // the subject string for the last successful match.
var lastMatchInfo = [ var lastMatchInfo = [
2, // REGEXP_NUMBER_OF_CAPTURES 2, // REGEXP_NUMBER_OF_CAPTURES
0, // REGEXP_FIRST_CAPTURE + 0
0, // REGEXP_FIRST_CAPTURE + 1
"", // Last subject. "", // Last subject.
void 0, // Last input - settable with RegExpSetInput. void 0, // Last input - settable with RegExpSetInput.
0, // REGEXP_FIRST_CAPTURE + 0
0, // REGEXP_FIRST_CAPTURE + 1
]; ];
// ------------------------------------------------------------------- // -------------------------------------------------------------------
...@@ -353,8 +353,7 @@ function SetupRegExp() { ...@@ -353,8 +353,7 @@ function SetupRegExp() {
return IS_UNDEFINED(regExpInput) ? "" : regExpInput; return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
} }
function RegExpSetInput(string) { function RegExpSetInput(string) {
lastMatchInfo[lastMatchInfo[REGEXP_NUMBER_OF_CAPTURES] + 2] = LAST_INPUT(lastMatchInfo) = ToString(string);
ToString(string);
}; };
// All these accessors are set with the 'never_used' flag set to true. // All these accessors are set with the 'never_used' flag set to true.
......
...@@ -236,7 +236,7 @@ function StringReplace(search, replace) { ...@@ -236,7 +236,7 @@ function StringReplace(search, replace) {
// needle is a string rather than a regexp. In this case we can't update // needle is a string rather than a regexp. In this case we can't update
// lastMatchArray without erroneously affecting the properties on the global // lastMatchArray without erroneously affecting the properties on the global
// RegExp object. // RegExp object.
var reusableMatchInfo = [2, -1, -1, "", ""]; var reusableMatchInfo = [2, "", "", -1, -1];
// Helper function for regular expressions in String.prototype.replace. // Helper function for regular expressions in String.prototype.replace.
......
...@@ -74,7 +74,6 @@ function GlobalIsFinite(number) { ...@@ -74,7 +74,6 @@ function GlobalIsFinite(number) {
// ECMA-262 - 15.1.2.2 // ECMA-262 - 15.1.2.2
function GlobalParseInt(string, radix) { function GlobalParseInt(string, radix) {
if (radix === void 0) { if (radix === void 0) {
radix = 0;
// Some people use parseInt instead of Math.floor. This // Some people use parseInt instead of Math.floor. This
// optimization makes parseInt on a Smi 12 times faster (60ns // optimization makes parseInt on a Smi 12 times faster (60ns
// vs 800ns). The following optimization makes parseInt on a // vs 800ns). The following optimization makes parseInt on a
...@@ -87,6 +86,7 @@ function GlobalParseInt(string, radix) { ...@@ -87,6 +86,7 @@ function GlobalParseInt(string, radix) {
// Truncate number. // Truncate number.
return string | 0; return string | 0;
} }
radix = 0;
} else { } else {
radix = TO_INT32(radix); radix = TO_INT32(radix);
if (!(radix == 0 || (2 <= radix && radix <= 36))) if (!(radix == 0 || (2 <= radix && radix <= 36)))
......
...@@ -641,18 +641,22 @@ TEST(MacroAssembler) { ...@@ -641,18 +641,22 @@ TEST(MacroAssembler) {
Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source)); Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source));
int captures[5]; int captures[5];
Handle<String> f1 = const uc16 str1[] = {'f', 'o', 'o', 'b', 'a', 'r'};
Factory::NewStringFromAscii(CStrVector("foobar")); Handle<String> f1_16 =
CHECK(IrregexpInterpreter::Match(array, f1, captures, 0)); Factory::NewStringFromTwoByte(Vector<const uc16>(str1, 6));
CHECK(IrregexpInterpreter::Match(array, f1_16, captures, 0));
CHECK_EQ(0, captures[0]); CHECK_EQ(0, captures[0]);
CHECK_EQ(3, captures[1]); CHECK_EQ(3, captures[1]);
CHECK_EQ(1, captures[2]); CHECK_EQ(1, captures[2]);
CHECK_EQ(2, captures[3]); CHECK_EQ(2, captures[3]);
CHECK_EQ(84, captures[4]); CHECK_EQ(84, captures[4]);
Handle<String> f2 = const uc16 str2[] = {'b', 'a', 'r', 'f', 'o', 'o'};
Factory::NewStringFromAscii(CStrVector("barfoo")); Handle<String> f2_16 =
CHECK(!IrregexpInterpreter::Match(array, f2, captures, 0)); Factory::NewStringFromTwoByte(Vector<const uc16>(str2, 6));
CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0));
CHECK_EQ(42, captures[0]); CHECK_EQ(42, captures[0]);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment