Commit 265715d9 authored by lrn@chromium.org's avatar lrn@chromium.org

Optimized regexp.test. No longer creates an intermediate string array.

Removed some handler code.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1402 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 55e57ec1
......@@ -309,6 +309,7 @@ static void SetAtomLastCapture(FixedArray* array,
String* subject,
int from,
int to) {
NoHandleAllocation no_handles;
RegExpImpl::SetLastCaptureCount(array, 2);
RegExpImpl::SetLastSubject(array, subject);
RegExpImpl::SetLastInput(array, subject);
......@@ -329,8 +330,11 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
if (value == -1) return Factory::null_value();
ASSERT(last_match_info->HasFastElements());
Handle<FixedArray> array(last_match_info->elements());
SetAtomLastCapture(*array, *subject, value, value + needle->length());
{
NoHandleAllocation no_handles;
FixedArray* array = last_match_info->elements();
SetAtomLastCapture(array, *subject, value, value + needle->length());
}
return last_match_info;
}
......@@ -452,7 +456,9 @@ bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re,
return false;
}
Handle<FixedArray> data(FixedArray::cast(re->data()));
NoHandleAllocation no_handles;
FixedArray* data = FixedArray::cast(re->data());
data->set(index, result.code);
int register_max = IrregexpMaxRegisterCount(data);
if (result.num_registers > register_max) {
......@@ -463,55 +469,46 @@ bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re,
}
int RegExpImpl::IrregexpMaxRegisterCount(Handle<FixedArray> re) {
int RegExpImpl::IrregexpMaxRegisterCount(FixedArray* re) {
return Smi::cast(
re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value();
}
void RegExpImpl::SetIrregexpMaxRegisterCount(Handle<FixedArray> re, int value) {
re->set(JSRegExp::kIrregexpMaxRegisterCountIndex,
Smi::FromInt(value));
void RegExpImpl::SetIrregexpMaxRegisterCount(FixedArray* re, int value) {
re->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(value));
}
int RegExpImpl::IrregexpNumberOfCaptures(Handle<FixedArray> re) {
return Smi::cast(
re->get(JSRegExp::kIrregexpCaptureCountIndex))->value();
int RegExpImpl::IrregexpNumberOfCaptures(FixedArray* re) {
return Smi::cast(re->get(JSRegExp::kIrregexpCaptureCountIndex))->value();
}
int RegExpImpl::IrregexpNumberOfRegisters(Handle<FixedArray> re) {
return Smi::cast(
re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value();
int RegExpImpl::IrregexpNumberOfRegisters(FixedArray* re) {
return Smi::cast(re->get(JSRegExp::kIrregexpMaxRegisterCountIndex))->value();
}
Handle<ByteArray> RegExpImpl::IrregexpByteCode(Handle<FixedArray> re,
bool is_ascii) {
ByteArray* RegExpImpl::IrregexpByteCode(FixedArray* re, bool is_ascii) {
int index;
if (is_ascii) {
index = JSRegExp::kIrregexpASCIICodeIndex;
} else {
index = JSRegExp::kIrregexpUC16CodeIndex;
}
Object* value = re->get(index);
ASSERT(value->IsByteArray());
return Handle<ByteArray>(ByteArray::cast(value));
return ByteArray::cast(re->get(index));
}
Handle<Code> RegExpImpl::IrregexpNativeCode(Handle<FixedArray> re,
bool is_ascii) {
Code* RegExpImpl::IrregexpNativeCode(FixedArray* re, bool is_ascii) {
int index;
if (is_ascii) {
index = JSRegExp::kIrregexpASCIICodeIndex;
} else {
index = JSRegExp::kIrregexpUC16CodeIndex;
}
Object* value = re->get(index);
ASSERT(value->IsCode());
return Handle<Code>(Code::cast(value));
return Code::cast(re->get(index));
}
......@@ -542,7 +539,7 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
// Prepare space for the return values.
Handle<FixedArray> re_data(FixedArray::cast(regexp->data()));
int number_of_capture_registers =
(IrregexpNumberOfCaptures(re_data) + 1) * 2;
(IrregexpNumberOfCaptures(*re_data) + 1) * 2;
OffsetsVector offsets(number_of_capture_registers);
int previous_index = index;
......@@ -584,7 +581,7 @@ Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
// Prepare space for the return values.
int number_of_capture_registers =
(IrregexpNumberOfCaptures(irregexp) + 1) * 2;
(IrregexpNumberOfCaptures(*irregexp) + 1) * 2;
OffsetsVector offsets(number_of_capture_registers);
int previous_index = 0;
......@@ -670,7 +667,7 @@ Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> regexp,
if (FLAG_regexp_native) {
#ifndef ARM
Handle<Code> code(IrregexpNativeCode(regexp, is_ascii));
Handle<Code> code(IrregexpNativeCode(*regexp, is_ascii));
// Character offsets into string.
int start_offset = previous_index;
......@@ -746,7 +743,7 @@ Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> regexp,
for (int i = number_of_capture_registers - 1; i >= 0; i--) {
offsets_vector[i] = -1;
}
Handle<ByteArray> byte_codes = IrregexpByteCode(regexp, is_ascii);
Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));
rc = IrregexpInterpreter::Match(byte_codes,
subject,
......
......@@ -139,13 +139,12 @@ class RegExpImpl {
static bool EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii);
static int IrregexpMaxRegisterCount(Handle<FixedArray> re);
static void SetIrregexpMaxRegisterCount(Handle<FixedArray> re, int value);
static int IrregexpNumberOfCaptures(Handle<FixedArray> re);
static int IrregexpNumberOfRegisters(Handle<FixedArray> re);
static Handle<ByteArray> IrregexpByteCode(Handle<FixedArray> re,
bool is_ascii);
static Handle<Code> IrregexpNativeCode(Handle<FixedArray> re, bool is_ascii);
static int IrregexpMaxRegisterCount(FixedArray* re);
static void SetIrregexpMaxRegisterCount(FixedArray* re, int value);
static int IrregexpNumberOfCaptures(FixedArray* re);
static int IrregexpNumberOfRegisters(FixedArray* re);
static ByteArray* IrregexpByteCode(FixedArray* re, bool is_ascii);
static Code* IrregexpNativeCode(FixedArray* re, bool is_ascii);
// On a successful match, the result is a JSArray containing
// captured positions. On a failure, the result is the null value.
......
......@@ -196,10 +196,36 @@ function RegExpExec(string) {
// Section 15.10.6.3 doesn't actually make sense, but the intention seems to be
// that test is defined in terms of String.prototype.exec even if it changes.
// that test is defined in terms of String.prototype.exec even if the method is
// called on a non-RegExp object. However, it probably means the original
// value of String.prototype.exec, which is what everybody else implements.
function RegExpTest(string) {
var result = (%_ArgumentsLength() == 0) ? this.exec() : this.exec(string);
return result != null;
if (%_ArgumentsLength() == 0) {
var regExpInput = LAST_INPUT(lastMatchInfo);
if (IS_UNDEFINED(regExpInput)) {
throw MakeError('no_input_to_regexp', [this]);
}
string = regExpInput;
}
var s = ToString(string);
var length = s.length;
var lastIndex = this.lastIndex;
var i = this.global ? TO_INTEGER(lastIndex) : 0;
if (i < 0 || i > s.length) {
this.lastIndex = 0;
return false;
}
%_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %RegExpExec(this, s, i, lastMatchInfo);
if (matchIndices == null) {
if (this.global) this.lastIndex = 0;
return false;
}
return true;
}
......
......@@ -44,6 +44,8 @@ assertTrue(f2.ignoreCase);
// On the other hand test is defined in a semi-coherent way as a call to exec.
// 15.10.6.3
// SpiderMonkey fails this one.
// We match other browsers in using the original value of RegExp.prototype.exec.
// I.e., RegExp.prototype.test shouldn't use the current value of
// RegExp.prototype.exec.
RegExp.prototype.exec = function(string) { return 'x'; }
assertTrue(/f/.test('x'));
assertFalse(/f/.test('x'));
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