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() { ...@@ -1786,11 +1786,17 @@ int Map::inobject_properties() {
int HeapObject::SizeFromMap(Map* map) { int HeapObject::SizeFromMap(Map* map) {
InstanceType instance_type = map->instance_type(); InstanceType instance_type = map->instance_type();
// Only inline the two most frequent cases. // Only inline the most frequent cases.
if (instance_type == JS_OBJECT_TYPE) return map->instance_size(); 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) { if (instance_type == FIXED_ARRAY_TYPE) {
return reinterpret_cast<FixedArray*>(this)->FixedArraySize(); return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
} }
if (instance_type == BYTE_ARRAY_TYPE) {
return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
}
// Otherwise do the general size computation. // Otherwise do the general size computation.
return SlowSizeFromMap(map); return SlowSizeFromMap(map);
} }
......
...@@ -370,10 +370,10 @@ function addCaptureString(builder, matchInfo, index) { ...@@ -370,10 +370,10 @@ function addCaptureString(builder, matchInfo, index) {
// 'abcd'.replace(/(.)/g, function() { return RegExp.$1; } // 'abcd'.replace(/(.)/g, function() { return RegExp.$1; }
// should be 'abcd' and not 'dddd' (or anything else). // should be 'abcd' and not 'dddd' (or anything else).
function StringReplaceRegExpWithFunction(subject, regexp, replace) { function StringReplaceRegExpWithFunction(subject, regexp, replace) {
var result = new ReplaceResultBuilder(subject);
var lastMatchInfo = DoRegExpExec(regexp, subject, 0); var lastMatchInfo = DoRegExpExec(regexp, subject, 0);
if (IS_NULL(lastMatchInfo)) return subject; 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 // 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 // over all matches. The loop is not in C++ code here like the one in
// RegExp.prototype.exec, because of the interleaved function application. // RegExp.prototype.exec, because of the interleaved function application.
...@@ -498,10 +498,8 @@ function StringSlice(start, end) { ...@@ -498,10 +498,8 @@ function StringSlice(start, end) {
// ECMA-262 section 15.5.4.14 // ECMA-262 section 15.5.4.14
function StringSplit(separator, limit) { function StringSplit(separator, limit) {
var subject = ToString(this); var subject = ToString(this);
var result = []; limit = (limit === void 0) ? 0xffffffff : ToUint32(limit);
var lim = (limit === void 0) ? 0xffffffff : ToUint32(limit); if (limit === 0) return [];
if (lim === 0) return result;
// ECMA-262 says that if separator is undefined, the result should // ECMA-262 says that if separator is undefined, the result should
// be an array of size 1 containing the entire string. SpiderMonkey // be an array of size 1 containing the entire string. SpiderMonkey
...@@ -509,28 +507,31 @@ function StringSplit(separator, limit) { ...@@ -509,28 +507,31 @@ function StringSplit(separator, limit) {
// undefined is explicitly given, they convert it to a string and // undefined is explicitly given, they convert it to a string and
// use that. We do as SpiderMonkey and KJS. // use that. We do as SpiderMonkey and KJS.
if (%_ArgumentsLength() === 0) { if (%_ArgumentsLength() === 0) {
result[result.length] = subject; return [subject];
return result;
} }
var length = subject.length; var length = subject.length;
var currentIndex = 0;
var startIndex = 0;
var sep;
if (IS_REGEXP(separator)) { if (IS_REGEXP(separator)) {
sep = separator; %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
%_Log('regexp', 'regexp-split,%0S,%1r', [subject, sep]);
} else { } 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 (length === 0) {
if (splitMatch(sep, subject, 0, 0) != null) return result; if (splitMatch(separator, subject, 0, 0) != null) return [];
result[result.length] = subject; return [subject];
return result;
} }
var currentIndex = 0;
var startIndex = 0;
var result = [];
while (true) { while (true) {
if (startIndex === length) { if (startIndex === length) {
...@@ -538,7 +539,7 @@ function StringSplit(separator, limit) { ...@@ -538,7 +539,7 @@ function StringSplit(separator, limit) {
return result; return result;
} }
var lastMatchInfo = splitMatch(sep, subject, currentIndex, startIndex); var lastMatchInfo = splitMatch(separator, subject, currentIndex, startIndex);
if (IS_NULL(lastMatchInfo)) { if (IS_NULL(lastMatchInfo)) {
result[result.length] = subject.slice(currentIndex, length); result[result.length] = subject.slice(currentIndex, length);
...@@ -553,21 +554,18 @@ function StringSplit(separator, limit) { ...@@ -553,21 +554,18 @@ function StringSplit(separator, limit) {
continue; continue;
} }
result[result.length] = result[result.length] = SubString(subject, currentIndex, lastMatchInfo[CAPTURE0]);
SubString(subject, currentIndex, lastMatchInfo[CAPTURE0]); if (result.length === limit) return result;
if (result.length === lim) return result;
for (var i = 2; i < NUMBER_OF_CAPTURES(lastMatchInfo); i += 2) { for (var i = 2; i < NUMBER_OF_CAPTURES(lastMatchInfo); i += 2) {
var start = lastMatchInfo[CAPTURE(i)]; var start = lastMatchInfo[CAPTURE(i)];
var end = lastMatchInfo[CAPTURE(i + 1)]; var end = lastMatchInfo[CAPTURE(i + 1)];
if (start != -1 && end != -1) { if (start != -1 && end != -1) {
result[result.length] = SubString(subject, result[result.length] = SubString(subject, start, end);
lastMatchInfo[CAPTURE(i)],
lastMatchInfo[CAPTURE(i + 1)]);
} else { } else {
result[result.length] = void 0; result[result.length] = void 0;
} }
if (result.length === lim) return result; if (result.length === limit) return result;
} }
startIndex = currentIndex = endIndex; 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