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:
parent
7349746b22
commit
01f4cb0951
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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++) {
|
||||
|
@ -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];
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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]]));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user