From 977ad65073288546eb91f3cbab019e11e79298c5 Mon Sep 17 00:00:00 2001 From: "bak@chromium.org" Date: Tue, 16 Jun 2009 13:31:31 +0000 Subject: [PATCH] - Changed fast case for computing object size based on usage histogram. - Added fast case to String.prototype.split (Mads's idea). - Made minor other optimizations in String.prototype.split. Review URL: http://codereview.chromium.org/126201 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2191 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects-inl.h | 10 ++++++++-- src/string.js | 48 +++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/objects-inl.h b/src/objects-inl.h index d34e465..bac0d55 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1786,11 +1786,17 @@ int Map::inobject_properties() { int HeapObject::SizeFromMap(Map* map) { InstanceType instance_type = map->instance_type(); - // Only inline the two most frequent cases. - if (instance_type == JS_OBJECT_TYPE) return map->instance_size(); + // Only inline the most frequent cases. + if (instance_type == JS_OBJECT_TYPE || + (instance_type & (kIsNotStringMask | kStringRepresentationMask)) == + (kStringTag | kConsStringTag) || + instance_type == JS_ARRAY_TYPE) return map->instance_size(); if (instance_type == FIXED_ARRAY_TYPE) { return reinterpret_cast(this)->FixedArraySize(); } + if (instance_type == BYTE_ARRAY_TYPE) { + return reinterpret_cast(this)->ByteArraySize(); + } // Otherwise do the general size computation. return SlowSizeFromMap(map); } diff --git a/src/string.js b/src/string.js index df1f393..3d8a11b 100644 --- a/src/string.js +++ b/src/string.js @@ -370,10 +370,10 @@ function addCaptureString(builder, matchInfo, index) { // 'abcd'.replace(/(.)/g, function() { return RegExp.$1; } // should be 'abcd' and not 'dddd' (or anything else). function StringReplaceRegExpWithFunction(subject, regexp, replace) { - var result = new ReplaceResultBuilder(subject); var lastMatchInfo = DoRegExpExec(regexp, subject, 0); if (IS_NULL(lastMatchInfo)) return subject; + var result = new ReplaceResultBuilder(subject); // There's at least one match. If the regexp is global, we have to loop // over all matches. The loop is not in C++ code here like the one in // RegExp.prototype.exec, because of the interleaved function application. @@ -498,10 +498,8 @@ function StringSlice(start, end) { // ECMA-262 section 15.5.4.14 function StringSplit(separator, limit) { var subject = ToString(this); - var result = []; - var lim = (limit === void 0) ? 0xffffffff : ToUint32(limit); - - if (lim === 0) return result; + limit = (limit === void 0) ? 0xffffffff : ToUint32(limit); + if (limit === 0) return []; // ECMA-262 says that if separator is undefined, the result should // be an array of size 1 containing the entire string. SpiderMonkey @@ -509,28 +507,31 @@ function StringSplit(separator, limit) { // undefined is explicitly given, they convert it to a string and // use that. We do as SpiderMonkey and KJS. if (%_ArgumentsLength() === 0) { - result[result.length] = subject; - return result; + return [subject]; } var length = subject.length; - var currentIndex = 0; - var startIndex = 0; - - var sep; if (IS_REGEXP(separator)) { - sep = separator; - %_Log('regexp', 'regexp-split,%0S,%1r', [subject, sep]); + %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); } else { - sep = ToString(separator); + separator = ToString(separator); + // If the separator string is empty then return the elements in the subject. + if (separator.length == 0) { + var result = $Array(length); + for (var i = 0; i < length; i++) result[i] = subject[i]; + return result; + } } if (length === 0) { - if (splitMatch(sep, subject, 0, 0) != null) return result; - result[result.length] = subject; - return result; + if (splitMatch(separator, subject, 0, 0) != null) return []; + return [subject]; } + var currentIndex = 0; + var startIndex = 0; + var result = []; + while (true) { if (startIndex === length) { @@ -538,7 +539,7 @@ function StringSplit(separator, limit) { return result; } - var lastMatchInfo = splitMatch(sep, subject, currentIndex, startIndex); + var lastMatchInfo = splitMatch(separator, subject, currentIndex, startIndex); if (IS_NULL(lastMatchInfo)) { result[result.length] = subject.slice(currentIndex, length); @@ -553,21 +554,18 @@ function StringSplit(separator, limit) { continue; } - result[result.length] = - SubString(subject, currentIndex, lastMatchInfo[CAPTURE0]); - if (result.length === lim) return result; + result[result.length] = SubString(subject, currentIndex, lastMatchInfo[CAPTURE0]); + if (result.length === limit) return result; for (var i = 2; i < NUMBER_OF_CAPTURES(lastMatchInfo); i += 2) { var start = lastMatchInfo[CAPTURE(i)]; var end = lastMatchInfo[CAPTURE(i + 1)]; if (start != -1 && end != -1) { - result[result.length] = SubString(subject, - lastMatchInfo[CAPTURE(i)], - lastMatchInfo[CAPTURE(i + 1)]); + result[result.length] = SubString(subject, start, end); } else { result[result.length] = void 0; } - if (result.length === lim) return result; + if (result.length === limit) return result; } startIndex = currentIndex = endIndex; -- 2.7.4