Commit 977ad650 authored by bak@chromium.org's avatar bak@chromium.org

- 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
parent 01216a06
......@@ -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<FixedArray*>(this)->FixedArraySize();
}
if (instance_type == BYTE_ARRAY_TYPE) {
return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
}
// Otherwise do the general size computation.
return SlowSizeFromMap(map);
}
......
......@@ -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;
......
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