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() {
void Heap::GarbageCollectionPrologue() {
RegExpImpl::NewSpaceCollectionPrologue();
gc_count_++;
#ifdef DEBUG
ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
......@@ -423,6 +424,7 @@ void Heap::MarkCompact(GCTracer* tracer) {
void Heap::MarkCompactPrologue() {
CompilationCache::MarkCompactPrologue();
RegExpImpl::OldSpaceCollectionPrologue();
Top::MarkCompactPrologue();
ThreadManager::MarkCompactPrologue();
}
......
......@@ -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<String> pattern,
Handle<String> flags,
......@@ -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;
......@@ -127,14 +189,7 @@ Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject) {
switch (regexp->type_tag()) {
case JSRegExp::JSCRE:
FlattenString(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);
}
return JsreExecGlobal(regexp, subject);
case JSRegExp::ATOM:
return AtomExecGlobal(regexp, subject);
default:
......@@ -213,6 +268,8 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
if (flags->Get(i) == 'm') multiline_option = JSRegExpMultiline;
}
Handle<String> two_byte_pattern = StringToTwoByte(pattern);
unsigned number_of_captures;
const char* error_message = NULL;
......@@ -222,31 +279,14 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
bool first_time = true;
while (true) {
first_time = false;
malloc_failure = Failure::Exception();
if (pattern->IsAsciiRepresentation()) {
Vector<const char> contents = pattern->ToAsciiVector();
code = jsRegExpCompile(contents.start(),
contents.length(),
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);
}
code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(),
pattern->length(), case_option,
multiline_option, &number_of_captures,
&error_message, &JSREMalloc, &JSREFree);
if (code == NULL) {
if (first_time && malloc_failure->IsRetryAfterGC()) {
first_time = false;
if (!Heap::CollectGarbage(malloc_failure->requested(),
malloc_failure->allocation_space())) {
// TODO(1181417): Fix this.
......@@ -287,12 +327,11 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
}
template <typename T>
Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
int num_captures,
Handle<String> subject,
int previous_index,
Vector<const T> contents,
const uc16* two_byte_subject,
int* offsets_vector,
int offsets_vector_length) {
int rc;
......@@ -304,9 +343,9 @@ Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
LOG(RegExpExecEvent(regexp, previous_index, subject));
rc = jsRegExpExecute<T>(js_regexp,
contents.start(),
contents.length(),
rc = jsRegExpExecute(js_regexp,
two_byte_subject,
subject->length(),
previous_index,
offsets_vector,
offsets_vector_length);
......@@ -391,29 +430,19 @@ Handle<Object> RegExpImpl::JsreExec(Handle<JSRegExp> regexp,
int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
FlattenString(subject);
if (subject->IsAsciiRepresentation()) {
Vector<const char> contents = subject->ToAsciiVector();
Handle<Object> result(JsreExecOnce(regexp, num_captures, subject,
previous_index,
contents,
offsets.vector(), offsets.length()));
return result;
} else {
Vector<const uc16> contents = subject->ToUC16Vector();
Handle<String> subject16 = CachedStringToTwoByte(subject);
Handle<Object> result(JsreExecOnce(regexp, num_captures, subject,
previous_index,
contents,
subject16->GetTwoByteData(),
offsets.vector(), offsets.length()));
return result;
}
}
template <typename T>
Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject,
Vector<const T> contents) {
Handle<String> subject) {
// Prepare space for the return values.
int num_captures = JsreCapture(regexp);
......@@ -425,19 +454,17 @@ Handle<Object> RegExpImpl::JsreExecGlobal(Handle<JSRegExp> regexp,
int i = 0;
Handle<Object> matches;
Handle<String> subject16 = CachedStringToTwoByte(subject);
do {
if (previous_index > subject->length() || previous_index < 0) {
// Per ECMA-262 15.10.6.2, if the previous index is greater than the
// string length, there is no match.
matches = Factory::null_value();
} else {
matches = JsreExecOnce<T>(regexp,
num_captures,
subject,
previous_index,
contents,
offsets.vector(),
offsets.length());
matches = JsreExecOnce(regexp, num_captures, subject, previous_index,
subject16->GetTwoByteData(),
offsets.vector(), offsets.length());
if (matches->IsJSArray()) {
SetElement(result, i, matches);
......
......@@ -79,24 +79,32 @@ class RegExpImpl {
Handle<String> subject,
Handle<Object> index);
template <typename T>
static Handle<Object> JsreExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject,
Vector<const T> contents);
Handle<String> subject);
static void NewSpaceCollectionPrologue();
static void OldSpaceCollectionPrologue();
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.
static int JsreCapture(Handle<JSRegExp> re);
static ByteArray* JsreInternal(Handle<JSRegExp> re);
// Call jsRegExpExecute once
template <typename T>
static Handle<Object> JsreExecOnce(Handle<JSRegExp> regexp,
int num_captures,
Handle<String> subject,
int previous_index,
Vector<const T> contents,
const uc16* utf8_subject,
int* ovector,
int ovector_length);
......
This diff is collapsed.
......@@ -1304,9 +1304,26 @@ class JSObject: public HeapObject {
JSFunction* function,
PropertyAttributes attributes);
// Replace a constant function property on a fast-case object.
Object* ReplaceConstantFunctionProperty(String* name,
Object* value);
Object* ReplaceSlowProperty(String* name,
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.
Object* AddFastProperty(String* name,
......@@ -1378,6 +1395,10 @@ class JSObject: public HeapObject {
static const uint32_t kMaxGap = 1024;
static const int kMaxFastElementsLength = 5000;
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.
static const int kPropertiesOffset = HeapObject::kHeaderSize;
......@@ -1563,7 +1584,6 @@ class DescriptorArray: public FixedArray {
inline void Get(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
// remove map transitions. If the descriptor is already present, it is
......@@ -1573,20 +1593,6 @@ class DescriptorArray: public FixedArray {
// a transition, they must not be removed. All null descriptors are removed.
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
// removed, or a Failure object if the new array could not be allocated.
Object* RemoveTransitions();
......
......@@ -66,15 +66,13 @@ const int JSRegExpErrorInternal = -4;
typedef void* malloc_t(size_t size);
typedef void free_t(void* address);
template <typename Char>
JSRegExp* jsRegExpCompile(const Char* pattern, int patternLength,
JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
JSRegExpIgnoreCaseOption, JSRegExpMultilineOption,
unsigned* numSubpatterns, const char** errorMessage,
malloc_t* allocate_function, free_t* free_function);
template <typename Char>
int jsRegExpExecute(const JSRegExp*,
const Char* subject, int subjectLength, int startOffset,
const UChar* subject, int subjectLength, int startOffset,
int* offsetsVector, int offsetsVectorLength);
void jsRegExpFree(JSRegExp*);
......
......@@ -147,8 +147,7 @@ struct CompileData {
/* Definitions to allow mutual recursion */
template <typename Char>
static bool compileBracket(int, int*, unsigned char**, const Char**, const Char*, ErrorCode*, int, int*, int*, CompileData&);
static bool compileBracket(int, int*, unsigned char**, const UChar**, const UChar*, ErrorCode*, int, int*, int*, CompileData&);
static bool bracketIsAnchored(const unsigned char* code);
static bool bracketNeedsLineStart(const unsigned char* code, unsigned captureMap, unsigned backrefMap);
static int bracketFindFirstAssertedCharacter(const unsigned char* code, bool inassert);
......@@ -175,10 +174,9 @@ Returns: zero or positive => a data character
on error, errorptr is set
*/
template <typename Char>
static int checkEscape(const Char** ptrptr, const Char* patternEnd, ErrorCode* errorcodeptr, int bracount, bool isclass)
static int checkEscape(const UChar** ptrptr, const UChar* patternEnd, ErrorCode* errorcodeptr, int bracount, bool isclass)
{
const Char* ptr = *ptrptr + 1;
const UChar* ptr = *ptrptr + 1;
/* If backslash is at the end of the pattern, it's an error. */
if (ptr == patternEnd) {
......@@ -221,7 +219,7 @@ static int checkEscape(const Char** ptrptr, const Char* patternEnd, ErrorCode* e
or when we overflow 0-255, whichever comes first. */
if (!isclass) {
const Char* oldptr = ptr;
const UChar* oldptr = ptr;
c -= '0';
while ((ptr + 1 < patternEnd) && isASCIIDigit(ptr[1]) && c <= bracount)
c = c * 10 + *(++ptr) - '0';
......@@ -325,8 +323,7 @@ Arguments:
Returns: true or false
*/
template <typename Char>
static bool isCountedRepeat(const Char* p, const Char* patternEnd)
static bool isCountedRepeat(const UChar* p, const UChar* patternEnd)
{
if (p >= patternEnd || !isASCIIDigit(*p))
return false;
......@@ -369,8 +366,7 @@ Returns: pointer to '}' on success;
current ptr on error, with errorcodeptr set non-zero
*/
template <typename Char>
static const Char* readRepeatCounts(const Char* p, int* minp, int* maxp, ErrorCode* errorcodeptr)
static const UChar* readRepeatCounts(const UChar* p, int* minp, int* maxp, ErrorCode* errorcodeptr)
{
int min = 0;
int max = -1;
......@@ -549,16 +545,14 @@ Returns: true on success
false, with *errorcodeptr set non-zero on error
*/
template <typename Char>
static inline bool safelyCheckNextChar(const Char* ptr, const Char* patternEnd, char expected)
static inline bool safelyCheckNextChar(const UChar* ptr, const UChar* patternEnd, UChar expected)
{
return ((ptr + 1 < patternEnd) && ptr[1] == expected);
}
template <typename Char>
static bool
compileBranch(int options, int* brackets, unsigned char** codeptr,
const Char** ptrptr, const Char* patternEnd, ErrorCode* errorcodeptr, int *firstbyteptr,
const UChar** ptrptr, const UChar* patternEnd, ErrorCode* errorcodeptr, int *firstbyteptr,
int* reqbyteptr, CompileData& cd)
{
int repeat_type, op_type;
......@@ -569,8 +563,8 @@ compileBranch(int options, int* brackets, unsigned char** codeptr,
unsigned char* code = *codeptr;
unsigned char* tempcode;
bool groupsetfirstbyte = false;
const Char* ptr = *ptrptr;
const Char* tempptr;
const UChar* ptr = *ptrptr;
const UChar* tempptr;
unsigned char* previous = NULL;
unsigned char classbits[32];
......@@ -800,7 +794,7 @@ compileBranch(int options, int* brackets, unsigned char** codeptr,
in such circumstances. */
if (d == '\\') {
const Char* oldptr = ptr;
const UChar* oldptr = ptr;
d = checkEscape(&ptr, patternEnd, errorcodeptr, cd.numCapturingBrackets, true);
/* \X is literal X; any other special means the '-' was literal */
......@@ -1709,13 +1703,12 @@ Argument:
Returns: true on success
*/
template <typename Char>
static bool
compileBracket(int options, int* brackets, unsigned char** codeptr,
const Char** ptrptr, const Char* patternEnd, ErrorCode* errorcodeptr, int skipbytes,
const UChar** ptrptr, const UChar* patternEnd, ErrorCode* errorcodeptr, int skipbytes,
int* firstbyteptr, int* reqbyteptr, CompileData& cd)
{
const Char* ptr = *ptrptr;
const UChar* ptr = *ptrptr;
unsigned char* code = *codeptr;
unsigned char* last_branch = code;
unsigned char* start_bracket = code;
......@@ -2002,8 +1995,7 @@ static inline int multiplyWithOverflowCheck(int a, int b)
return a * b;
}
template <typename Char>
static int calculateCompiledPatternLength(const Char* pattern, int patternLength, JSRegExpIgnoreCaseOption ignoreCase,
static int calculateCompiledPatternLength(const UChar* pattern, int patternLength, JSRegExpIgnoreCaseOption ignoreCase,
CompileData& cd, ErrorCode& errorcode)
{
/* Make a pass over the pattern to compute the
......@@ -2023,8 +2015,8 @@ static int calculateCompiledPatternLength(const Char* pattern, int patternLength
unsigned char bralenstack[BRASTACK_SIZE];
int bracount = 0;
const Char* ptr = (const Char*)(pattern - 1);
const Char* patternEnd = (const Char*)(pattern + patternLength);
const UChar* ptr = (const UChar*)(pattern - 1);
const UChar* patternEnd = (const UChar*)(pattern + patternLength);
while (++ptr < patternEnd) {
int minRepeats = 0, maxRepeats = 0;
......@@ -2200,7 +2192,7 @@ static int calculateCompiledPatternLength(const Char* pattern, int patternLength
int d = -1;
if (safelyCheckNextChar(ptr, patternEnd, '-')) {
Char const *hyptr = ptr++;
UChar const *hyptr = ptr++;
if (safelyCheckNextChar(ptr, patternEnd, '\\')) {
ptr++;
d = checkEscape(&ptr, patternEnd, &errorcode, cd.numCapturingBrackets, true);
......@@ -2545,8 +2537,7 @@ static inline JSRegExp* returnError(ErrorCode errorcode, const char** errorptr)
return 0;
}
template <typename Char>
JSRegExp* jsRegExpCompile(const Char* pattern, int patternLength,
JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
JSRegExpIgnoreCaseOption ignoreCase, JSRegExpMultilineOption multiline,
unsigned* numSubpatterns, const char** errorptr,
malloc_t* allocate_function, free_t* free_function)
......@@ -2587,8 +2578,8 @@ JSRegExp* jsRegExpCompile(const Char* pattern, int patternLength,
error, errorcode will be set non-zero, so we don't need to look at the result
of the function here. */
const Char* ptr = (const Char*)pattern;
const Char* patternEnd = pattern + patternLength;
const UChar* ptr = (const UChar*)pattern;
const UChar* patternEnd = pattern + patternLength;
unsigned char* code = (unsigned char*)codeStart;
int firstbyte, reqbyte;
int bracketCount = 0;
......@@ -2676,26 +2667,6 @@ JSRegExp* jsRegExpCompile(const Char* pattern, int patternLength,
return re;
}
template
JSRegExp* jsRegExpCompile<unsigned short>(const unsigned short* pattern,
int patternLength,
JSRegExpIgnoreCaseOption ignoreCase,
JSRegExpMultilineOption multiline,
unsigned* numSubpatterns,
const char** errorptr,
malloc_t* allocate_function,
free_t* free_function);
template
JSRegExp* jsRegExpCompile<char>(const char* pattern,
int patternLength,
JSRegExpIgnoreCaseOption ignoreCase,
JSRegExpMultilineOption multiline,
unsigned* numSubpatterns,
const char** errorptr,
malloc_t* allocate_function,
free_t* free_function);
void jsRegExpFree(JSRegExp* re, free_t* free_function)
{
(*free_function)(reinterpret_cast<void*>(re));
......
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