Introduce InternalPackedArray.

R=jkummerow@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/12255049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13678 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2013-02-15 15:20:05 +00:00
parent 7349746b22
commit 01f4cb0951
7 changed files with 90 additions and 62 deletions

View File

@ -1559,6 +1559,12 @@ function SetUpArray() {
"push", getFunction("push", ArrayPush),
"splice", getFunction("splice", ArraySplice)
));
SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
"join", getFunction("join", ArrayJoin),
"pop", getFunction("pop", ArrayPop),
"push", getFunction("push", ArrayPush)
));
}
SetUpArray();

View File

@ -204,6 +204,9 @@ class Genesis BASE_EMBEDDED {
// Used for creating a context from scratch.
void InstallNativeFunctions();
void InstallExperimentalNativeFunctions();
Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
const char* name,
ElementsKind elements_kind);
bool InstallNatives();
bool InstallExperimentalNatives();
void InstallBuiltinFunctionIds();
@ -1440,6 +1443,60 @@ void Genesis::InstallExperimentalNativeFunctions() {
#undef INSTALL_NATIVE
Handle<JSFunction> Genesis::InstallInternalArray(
Handle<JSBuiltinsObject> builtins,
const char* name,
ElementsKind elements_kind) {
// --- I n t e r n a l A r r a y ---
// An array constructor on the builtins object that works like
// the public Array constructor, except that its prototype
// doesn't inherit from Object.prototype.
// To be used only for internal work by builtins. Instances
// must not be leaked to user code.
Handle<JSFunction> array_function =
InstallFunction(builtins,
name,
JS_ARRAY_TYPE,
JSArray::kSize,
isolate()->initial_object_prototype(),
Builtins::kInternalArrayCode,
true);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(array_function, prototype);
array_function->shared()->set_construct_stub(
isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
MaybeObject* maybe_map = array_function->initial_map()->Copy();
Map* new_map;
if (!maybe_map->To(&new_map)) return Handle<JSFunction>::null();
new_map->set_elements_kind(elements_kind);
array_function->set_initial_map(new_map);
// Make "length" magic on instances.
Handle<Map> initial_map(array_function->initial_map());
Handle<DescriptorArray> array_descriptors(
factory()->NewDescriptorArray(0, 1));
DescriptorArray::WhitenessWitness witness(*array_descriptors);
Handle<Foreign> array_length(factory()->NewForeign(
&Accessors::ArrayLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
initial_map->set_instance_descriptors(*array_descriptors);
{ // Add length.
CallbacksDescriptor d(
*factory()->length_symbol(), *array_length, attribs);
array_function->initial_map()->AppendDescriptor(&d, witness);
}
return array_function;
}
bool Genesis::InstallNatives() {
HandleScope scope(isolate());
@ -1662,60 +1719,25 @@ bool Genesis::InstallNatives() {
native_context()->set_opaque_reference_function(*opaque_reference_fun);
}
{ // --- I n t e r n a l A r r a y ---
// An array constructor on the builtins object that works like
// the public Array constructor, except that its prototype
// doesn't inherit from Object.prototype.
// To be used only for internal work by builtins. Instances
// must not be leaked to user code.
// InternalArrays should not use Smi-Only array optimizations. There are too
// many places in the C++ runtime code (e.g. RegEx) that assume that
// elements in InternalArrays can be set to non-Smi values without going
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
{
Handle<JSFunction> array_function =
InstallFunction(builtins,
"InternalArray",
JS_ARRAY_TYPE,
JSArray::kSize,
isolate()->initial_object_prototype(),
Builtins::kInternalArrayCode,
true);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(array_function, prototype);
array_function->shared()->set_construct_stub(
isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
// InternalArrays should not use Smi-Only array optimizations. There are too
// many places in the C++ runtime code (e.g. RegEx) that assume that
// elements in InternalArrays can be set to non-Smi values without going
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
MaybeObject* maybe_map = array_function->initial_map()->Copy();
Map* new_map;
if (!maybe_map->To(&new_map)) return false;
new_map->set_elements_kind(FAST_HOLEY_ELEMENTS);
array_function->set_initial_map(new_map);
// Make "length" magic on instances.
Handle<Map> initial_map(array_function->initial_map());
Handle<DescriptorArray> array_descriptors(
factory()->NewDescriptorArray(0, 1));
DescriptorArray::WhitenessWitness witness(*array_descriptors);
Handle<Foreign> array_length(factory()->NewForeign(
&Accessors::ArrayLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
initial_map->set_instance_descriptors(*array_descriptors);
{ // Add length.
CallbacksDescriptor d(
*factory()->length_symbol(), *array_length, attribs);
array_function->initial_map()->AppendDescriptor(&d, witness);
}
InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
if (array_function.is_null()) return false;
native_context()->set_internal_array_function(*array_function);
}
{
Handle<JSFunction> array_function =
InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
if (array_function.is_null()) return false;
}
if (FLAG_disable_native_files) {
PrintF("Warning: Running without installed natives!\n");
return true;
@ -1789,7 +1811,9 @@ bool Genesis::InstallNatives() {
// Add initial map.
Handle<Map> initial_map =
factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
factory()->NewMap(JS_ARRAY_TYPE,
JSRegExpResult::kSize,
FAST_ELEMENTS);
initial_map->set_constructor(*array_constructor);
// Set prototype on map.

View File

@ -67,7 +67,7 @@ function SerializeArray(value, replacer, stack, indent, gap) {
}
var stepback = indent;
indent += gap;
var partial = new InternalArray();
var partial = new InternalPackedArray();
var len = value.length;
for (var i = 0; i < len; i++) {
var strP = JSONSerialize($String(i), value, replacer, stack,
@ -97,7 +97,7 @@ function SerializeObject(value, replacer, stack, indent, gap) {
}
var stepback = indent;
indent += gap;
var partial = new InternalArray();
var partial = new InternalPackedArray();
if (IS_ARRAY(replacer)) {
var length = replacer.length;
for (var i = 0; i < length; i++) {

View File

@ -557,7 +557,7 @@ function ScriptNameOrSourceURL() {
// Don't reuse lastMatchInfo here, so we create a new array with room
// for four captures (array with length one longer than the index
// of the fourth capture, where the numbering is zero-based).
var matchInfo = new InternalArray(CAPTURE(3) + 1);
var matchInfo = new InternalPackedArray(CAPTURE(3) + 1);
var match =
%_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
if (match) {
@ -1033,7 +1033,7 @@ function FormatErrorString(error) {
function GetStackFrames(raw_stack) {
var frames = new InternalArray();
var frames = new InternalPackedArray();
for (var i = 0; i < raw_stack.length; i += 4) {
var recv = raw_stack[i];
var fun = raw_stack[i + 1];
@ -1047,7 +1047,7 @@ function GetStackFrames(raw_stack) {
function FormatStackTrace(error_string, frames) {
var lines = new InternalArray();
var lines = new InternalPackedArray();
lines.push(error_string);
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];

View File

@ -385,7 +385,7 @@ function RegExpMakeCaptureGetter(n) {
// pairs for the match and all the captured substrings), the invariant is
// that there are at least two capture indeces. The array also contains
// the subject string for the last successful match.
var lastMatchInfo = new InternalArray(
var lastMatchInfo = new InternalPackedArray(
2, // REGEXP_NUMBER_OF_CAPTURES
"", // Last subject.
void 0, // Last input - settable with RegExpSetInput.

View File

@ -420,7 +420,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
// input string and some replacements that were returned from the replace
// function.
var match_start = 0;
var override = new InternalArray(null, 0, subject);
var override = new InternalPackedArray(null, 0, subject);
var receiver = %GetDefaultReceiver(replace);
for (var i = 0; i < len; i++) {
var elem = res[i];
@ -821,8 +821,6 @@ function StringTrimRight() {
return %StringTrim(TO_STRING_INLINE(this), false, true);
}
var static_charcode_array = new InternalArray(4);
// ECMA-262, section 15.5.3.2
function StringFromCharCode(code) {

View File

@ -1117,7 +1117,7 @@ function ObjectDefineProperty(obj, p, attributes) {
function GetOwnEnumerablePropertyNames(properties) {
var names = new InternalArray();
var names = new InternalPackedArray();
for (var key in properties) {
if (%HasLocalProperty(properties, key)) {
names.push(key);
@ -1134,7 +1134,7 @@ function ObjectDefineProperties(obj, properties) {
}
var props = ToObject(properties);
var names = GetOwnEnumerablePropertyNames(props);
var descriptors = new InternalArray();
var descriptors = new InternalPackedArray();
for (var i = 0; i < names.length; i++) {
descriptors.push(ToPropertyDescriptor(props[names[i]]));
}