Reverted the changes to jscre because the arm cross-compiler dies with

an internal error when compiling templateified jscre.  We really need
to update that damn arm compiler.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@478 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 89ac41af
...@@ -223,6 +223,7 @@ void Heap::ReportStatisticsAfterGC() { ...@@ -223,6 +223,7 @@ void Heap::ReportStatisticsAfterGC() {
void Heap::GarbageCollectionPrologue() { void Heap::GarbageCollectionPrologue() {
RegExpImpl::NewSpaceCollectionPrologue();
gc_count_++; gc_count_++;
#ifdef DEBUG #ifdef DEBUG
ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
...@@ -423,6 +424,7 @@ void Heap::MarkCompact(GCTracer* tracer) { ...@@ -423,6 +424,7 @@ void Heap::MarkCompact(GCTracer* tracer) {
void Heap::MarkCompactPrologue() { void Heap::MarkCompactPrologue() {
CompilationCache::MarkCompactPrologue(); CompilationCache::MarkCompactPrologue();
RegExpImpl::OldSpaceCollectionPrologue();
Top::MarkCompactPrologue(); Top::MarkCompactPrologue();
ThreadManager::MarkCompactPrologue(); ThreadManager::MarkCompactPrologue();
} }
......
...@@ -65,6 +65,27 @@ static void JSREFree(void* p) { ...@@ -65,6 +65,27 @@ static void JSREFree(void* p) {
} }
String* RegExpImpl::last_ascii_string_ = NULL;
String* RegExpImpl::two_byte_cached_string_ = NULL;
void RegExpImpl::NewSpaceCollectionPrologue() {
// The two byte string is always in the old space. The Ascii string may be
// in either place. If it is in the old space we don't need to do anything.
if (Heap::InNewSpace(last_ascii_string_)) {
// Invalidate the cache.
last_ascii_string_ = NULL;
two_byte_cached_string_ = NULL;
}
}
void RegExpImpl::OldSpaceCollectionPrologue() {
last_ascii_string_ = NULL;
two_byte_cached_string_ = NULL;
}
Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor, Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor,
Handle<String> pattern, Handle<String> pattern,
Handle<String> flags, Handle<String> flags,
...@@ -81,6 +102,47 @@ Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor, ...@@ -81,6 +102,47 @@ Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor,
} }
// Converts a source string to a 16 bit flat string or a SlicedString containing
// a 16 bit flat string).
Handle<String> RegExpImpl::CachedStringToTwoByte(Handle<String> subject) {
if (*subject == last_ascii_string_) {
ASSERT(two_byte_cached_string_ != NULL);
return Handle<String>(String::cast(two_byte_cached_string_));
}
Handle<String> two_byte_string = StringToTwoByte(subject);
last_ascii_string_ = *subject;
two_byte_cached_string_ = *two_byte_string;
return two_byte_string;
}
// Converts a source string to a 16 bit flat string or a SlicedString containing
// a 16 bit flat string).
Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) {
if (!pattern->IsFlat()) {
FlattenString(pattern);
}
Handle<String> flat_string(pattern->IsConsString() ?
String::cast(ConsString::cast(*pattern)->first()) :
*pattern);
ASSERT(!flat_string->IsConsString());
ASSERT(flat_string->IsSeqString() || flat_string->IsSlicedString() ||
flat_string->IsExternalString());
if (!flat_string->IsAsciiRepresentation()) {
return flat_string;
}
Handle<String> two_byte_string =
Factory::NewRawTwoByteString(flat_string->length(), TENURED);
static StringInputBuffer convert_to_two_byte_buffer;
convert_to_two_byte_buffer.Reset(*flat_string);
for (int i = 0; convert_to_two_byte_buffer.has_more(); i++) {
two_byte_string->Set(i, convert_to_two_byte_buffer.GetNext());
}
return two_byte_string;
}
unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char; unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char;
...@@ -127,14 +189,7 @@ Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp, ...@@ -127,14 +189,7 @@ Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject) { Handle<String> subject) {
switch (regexp->type_tag()) { switch (regexp->type_tag()) {
case JSRegExp::JSCRE: case JSRegExp::JSCRE:
FlattenString(subject); return JsreExecGlobal(regexp, subject);
if (subject->IsAsciiRepresentation()) {
Vector<const char> contents = subject->ToAsciiVector();
return JsreExecGlobal(regexp, subject, contents);
} else {
Vector<const uc16> contents = subject->ToUC16Vector();
return JsreExecGlobal(regexp, subject, contents);
}
case JSRegExp::ATOM: case JSRegExp::ATOM:
return AtomExecGlobal(regexp, subject); return AtomExecGlobal(regexp, subject);
default: default:
...@@ -213,6 +268,8 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, ...@@ -213,6 +268,8 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
if (flags->Get(i) == 'm') multiline_option = JSRegExpMultiline; if (flags->Get(i) == 'm') multiline_option = JSRegExpMultiline;
} }
Handle<String> two_byte_pattern = StringToTwoByte(pattern);
unsigned number_of_captures; unsigned number_of_captures;
const char* error_message = NULL; const char* error_message = NULL;
...@@ -222,31 +279,14 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, ...@@ -222,31 +279,14 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
bool first_time = true; bool first_time = true;
while (true) { while (true) {
first_time = false;
malloc_failure = Failure::Exception(); malloc_failure = Failure::Exception();
if (pattern->IsAsciiRepresentation()) { code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(),
Vector<const char> contents = pattern->ToAsciiVector(); pattern->length(), case_option,
code = jsRegExpCompile(contents.start(), multiline_option, &number_of_captures,
contents.length(), &error_message, &JSREMalloc, &JSREFree);
case_option,
multiline_option,
&number_of_captures,
&error_message,
&JSREMalloc,
&JSREFree);
} else {
Vector<const uc16> contents = pattern->ToUC16Vector();
code = jsRegExpCompile(contents.start(),
contents.length(),
case_option,
multiline_option,
&number_of_captures,
&error_message,
&JSREMalloc,
&JSREFree);
}
if (code == NULL) { if (code == NULL) {
if (first_time && malloc_failure->IsRetryAfterGC()) { if (first_time && malloc_failure->IsRetryAfterGC()) {
first_time = false;
if (!Heap::CollectGarbage(malloc_failure->requested(), if (!Heap::CollectGarbage(malloc_failure->requested(),
malloc_failure->allocation_space())) { malloc_failure->allocation_space())) {
// TODO(1181417): Fix this. // TODO(1181417): Fix this.
...@@ -287,12 +327,11 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, ...@@ -287,12 +327,11 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
} }
template <typename T>
Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp, Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
int num_captures, int num_captures,
Handle<String> subject, Handle<String> subject,
int previous_index, int previous_index,
Vector<const T> contents, const uc16* two_byte_subject,
int* offsets_vector, int* offsets_vector,
int offsets_vector_length) { int offsets_vector_length) {
int rc; int rc;
...@@ -304,12 +343,12 @@ Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp, ...@@ -304,12 +343,12 @@ Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
LOG(RegExpExecEvent(regexp, previous_index, subject)); LOG(RegExpExecEvent(regexp, previous_index, subject));
rc = jsRegExpExecute<T>(js_regexp, rc = jsRegExpExecute(js_regexp,
contents.start(), two_byte_subject,
contents.length(), subject->length(),
previous_index, previous_index,
offsets_vector, offsets_vector,
offsets_vector_length); offsets_vector_length);
} }
// The KJS JavaScript engine returns null (ie, a failed match) when // The KJS JavaScript engine returns null (ie, a failed match) when
...@@ -391,29 +430,19 @@ Handle<Object> RegExpImpl::JsreExec(Handle<JSRegExp> regexp, ...@@ -391,29 +430,19 @@ Handle<Object> RegExpImpl::JsreExec(Handle<JSRegExp> regexp,
int previous_index = static_cast<int>(DoubleToInteger(index->Number())); int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
FlattenString(subject); Handle<String> subject16 = CachedStringToTwoByte(subject);
if (subject->IsAsciiRepresentation()) {
Vector<const char> contents = subject->ToAsciiVector(); Handle<Object> result(JsreExecOnce(regexp, num_captures, subject,
Handle<Object> result(JsreExecOnce(regexp, num_captures, subject, previous_index,
previous_index, subject16->GetTwoByteData(),
contents, offsets.vector(), offsets.length()));
offsets.vector(), offsets.length()));
return result; return result;
} else {
Vector<const uc16> contents = subject->ToUC16Vector();
Handle<Object> result(JsreExecOnce(regexp, num_captures, subject,
previous_index,
contents,
offsets.vector(), offsets.length()));
return result;
}
} }
template <typename T>
Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp, Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject, Handle<String> subject) {
Vector<const T> contents) {
// Prepare space for the return values. // Prepare space for the return values.
int num_captures = JsreCapture(regexp); int num_captures = JsreCapture(regexp);
...@@ -425,19 +454,17 @@ Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp, ...@@ -425,19 +454,17 @@ Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp,
int i = 0; int i = 0;
Handle<Object> matches; Handle<Object> matches;
Handle<String> subject16 = CachedStringToTwoByte(subject);
do { do {
if (previous_index > subject->length() || previous_index < 0) { if (previous_index > subject->length() || previous_index < 0) {
// Per ECMA-262 15.10.6.2, if the previous index is greater than the // Per ECMA-262 15.10.6.2, if the previous index is greater than the
// string length, there is no match. // string length, there is no match.
matches = Factory::null_value(); matches = Factory::null_value();
} else { } else {
matches = JsreExecOnce<T>(regexp, matches = JsreExecOnce(regexp, num_captures, subject, previous_index,
num_captures, subject16->GetTwoByteData(),
subject, offsets.vector(), offsets.length());
previous_index,
contents,
offsets.vector(),
offsets.length());
if (matches->IsJSArray()) { if (matches->IsJSArray()) {
SetElement(result, i, matches); SetElement(result, i, matches);
......
...@@ -79,24 +79,32 @@ class RegExpImpl { ...@@ -79,24 +79,32 @@ class RegExpImpl {
Handle<String> subject, Handle<String> subject,
Handle<Object> index); Handle<Object> index);
template <typename T>
static Handle<Object> JsreExecGlobal(Handle<JSRegExp> regexp, static Handle<Object> JsreExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject, Handle<String> subject);
Vector<const T> contents);
static void NewSpaceCollectionPrologue();
static void OldSpaceCollectionPrologue();
private: private:
// Converts a source string to a 16 bit flat string. The string
// will be either sequential or it will be a SlicedString backed
// by a flat string.
static Handle<String> StringToTwoByte(Handle<String> pattern);
static Handle<String> CachedStringToTwoByte(Handle<String> pattern);
static String* last_ascii_string_;
static String* two_byte_cached_string_;
// Returns the caputure from the re. // Returns the caputure from the re.
static int JsreCapture(Handle<JSRegExp> re); static int JsreCapture(Handle<JSRegExp> re);
static ByteArray* JsreInternal(Handle<JSRegExp> re); static ByteArray* JsreInternal(Handle<JSRegExp> re);
// Call jsRegExpExecute once // Call jsRegExpExecute once
template <typename T>
static Handle<Object> JsreExecOnce(Handle<JSRegExp> regexp, static Handle<Object> JsreExecOnce(Handle<JSRegExp> regexp,
int num_captures, int num_captures,
Handle<String> subject, Handle<String> subject,
int previous_index, int previous_index,
Vector<const T> contents, const uc16* utf8_subject,
int* ovector, int* ovector,
int ovector_length); int ovector_length);
......
This diff is collapsed.
...@@ -1304,9 +1304,26 @@ class JSObject: public HeapObject { ...@@ -1304,9 +1304,26 @@ class JSObject: public HeapObject {
JSFunction* function, JSFunction* function,
PropertyAttributes attributes); PropertyAttributes attributes);
// Replace a constant function property on a fast-case object. Object* ReplaceSlowProperty(String* name,
Object* ReplaceConstantFunctionProperty(String* name, Object* value,
Object* value); PropertyAttributes attributes);
// Converts a descriptor of any other type to a real field,
// backed by the properties array. Descriptors of visible
// types, such as CONSTANT_FUNCTION, keep their enumeration order.
// Converts the descriptor on the original object's map to a
// map transition, and the the new field is on the object's new map.
Object* ConvertDescriptorToFieldAndMapTransition(
String* name,
Object* new_value,
PropertyAttributes attributes);
// Converts a descriptor of any other type to a real field,
// backed by the properties array. Descriptors of visible
// types, such as CONSTANT_FUNCTION, keep their enumeration order.
Object* ConvertDescriptorToField(String* name,
Object* new_value,
PropertyAttributes attributes);
// Add a property to a fast-case object. // Add a property to a fast-case object.
Object* AddFastProperty(String* name, Object* AddFastProperty(String* name,
...@@ -1378,6 +1395,10 @@ class JSObject: public HeapObject { ...@@ -1378,6 +1395,10 @@ class JSObject: public HeapObject {
static const uint32_t kMaxGap = 1024; static const uint32_t kMaxGap = 1024;
static const int kMaxFastElementsLength = 5000; static const int kMaxFastElementsLength = 5000;
static const int kMaxFastProperties = 8; static const int kMaxFastProperties = 8;
// When extending the backing storage for property values, we increase
// its size by more than the 1 entry necessary, so sequentially adding fields
// to the same object requires fewer allocations and copies.
static const int kFieldsAdded = 3;
// Layout description. // Layout description.
static const int kPropertiesOffset = HeapObject::kHeaderSize; static const int kPropertiesOffset = HeapObject::kHeaderSize;
...@@ -1563,7 +1584,6 @@ class DescriptorArray: public FixedArray { ...@@ -1563,7 +1584,6 @@ class DescriptorArray: public FixedArray {
inline void Get(int descriptor_number, Descriptor* desc); inline void Get(int descriptor_number, Descriptor* desc);
inline void Set(int descriptor_number, Descriptor* desc); inline void Set(int descriptor_number, Descriptor* desc);
void ReplaceConstantFunction(int descriptor_number, JSFunction* value);
// Copy the descriptor array, insert a new descriptor and optionally // Copy the descriptor array, insert a new descriptor and optionally
// remove map transitions. If the descriptor is already present, it is // remove map transitions. If the descriptor is already present, it is
...@@ -1573,20 +1593,6 @@ class DescriptorArray: public FixedArray { ...@@ -1573,20 +1593,6 @@ class DescriptorArray: public FixedArray {
// a transition, they must not be removed. All null descriptors are removed. // a transition, they must not be removed. All null descriptors are removed.
Object* CopyInsert(Descriptor* descriptor, TransitionFlag transition_flag); Object* CopyInsert(Descriptor* descriptor, TransitionFlag transition_flag);
// Makes a copy of the descriptor array with the descriptor with key name
// removed. If name is the empty string, the descriptor array is copied.
// Transitions are removed if TransitionFlag is REMOVE_TRANSITIONS.
// All null descriptors are removed.
Object* CopyRemove(TransitionFlag remove_transitions, String* name);
// Copy the descriptor array, replace the property index and attributes
// of the named property, but preserve its enumeration index.
Object* CopyReplace(String* name, int index, PropertyAttributes attributes);
// Copy the descriptor array, removing the property index and attributes
// of the named property.
Object* CopyRemove(String* name);
// Remove all transitions. Return a copy of the array with all transitions // Remove all transitions. Return a copy of the array with all transitions
// removed, or a Failure object if the new array could not be allocated. // removed, or a Failure object if the new array could not be allocated.
Object* RemoveTransitions(); Object* RemoveTransitions();
......
...@@ -66,15 +66,13 @@ const int JSRegExpErrorInternal = -4; ...@@ -66,15 +66,13 @@ const int JSRegExpErrorInternal = -4;
typedef void* malloc_t(size_t size); typedef void* malloc_t(size_t size);
typedef void free_t(void* address); typedef void free_t(void* address);
template <typename Char> JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
JSRegExp* jsRegExpCompile(const Char* pattern, int patternLength,
JSRegExpIgnoreCaseOption, JSRegExpMultilineOption, JSRegExpIgnoreCaseOption, JSRegExpMultilineOption,
unsigned* numSubpatterns, const char** errorMessage, unsigned* numSubpatterns, const char** errorMessage,
malloc_t* allocate_function, free_t* free_function); malloc_t* allocate_function, free_t* free_function);
template <typename Char>
int jsRegExpExecute(const JSRegExp*, int jsRegExpExecute(const JSRegExp*,
const Char* subject, int subjectLength, int startOffset, const UChar* subject, int subjectLength, int startOffset,
int* offsetsVector, int offsetsVectorLength); int* offsetsVector, int offsetsVectorLength);
void jsRegExpFree(JSRegExp*); void jsRegExpFree(JSRegExp*);
......
This diff is collapsed.
This diff is collapsed.
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