Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1249)

Unified Diff: src/runtime.cc

Issue 7901016: Basic support for tracking smi-only arrays on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ready to land Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/bootstrapper.cc ('K') | « src/runtime.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index a51fcd35429917418bfc75b926f10f75d880dacf..cb6307250fa80a984911bfd5d8afb130b8baac54 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -177,6 +177,7 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
// Pixel elements cannot be created using an object literal.
ASSERT(!copy->HasExternalArrayElements());
switch (copy->GetElementsKind()) {
+ case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
FixedArray* elements = FixedArray::cast(copy->elements());
if (elements->map() == heap->fixed_cow_array_map()) {
@@ -189,6 +190,9 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
} else {
for (int i = 0; i < elements->length(); i++) {
Object* value = elements->get(i);
+ ASSERT(value->IsSmi() ||
+ value->IsTheHole() ||
+ (copy->GetElementsKind() == FAST_ELEMENTS));
if (value->IsJSObject()) {
JSObject* js_object = JSObject::cast(value);
{ MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
@@ -432,16 +436,28 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
is_cow ? elements : isolate->factory()->CopyFixedArray(elements);
Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
+ bool has_non_smi = false;
if (is_cow) {
-#ifdef DEBUG
// Copy-on-write arrays must be shallow (and simple).
- for (int i = 0; i < content->length(); i++) {
- ASSERT(!content->get(i)->IsFixedArray());
- }
+ if (FLAG_smi_only_arrays) {
+ for (int i = 0; i < content->length(); i++) {
+ Object* current = content->get(i);
+ ASSERT(!current->IsFixedArray());
+ if (!current->IsSmi()) {
+ has_non_smi = true;
+ }
+ }
+ } else {
+#if DEBUG
+ for (int i = 0; i < content->length(); i++) {
+ ASSERT(!content->get(i)->IsFixedArray());
+ }
#endif
+ }
} else {
for (int i = 0; i < content->length(); i++) {
- if (content->get(i)->IsFixedArray()) {
+ Object* current = content->get(i);
+ if (current->IsFixedArray()) {
// The value contains the constant_properties of a
// simple object or array literal.
Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
@@ -449,12 +465,25 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
CreateLiteralBoilerplate(isolate, literals, fa);
if (result.is_null()) return result;
content->set(i, *result);
+ has_non_smi = true;
+ } else {
+ if (!current->IsSmi()) {
+ has_non_smi = true;
+ }
}
}
}
// Set the elements.
- Handle<JSArray>::cast(object)->SetContent(*content);
+ Handle<JSArray> js_object(Handle<JSArray>::cast(object));
+ isolate->factory()->SetContent(js_object, content);
+
+ if (FLAG_smi_only_arrays) {
+ if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
+ isolate->factory()->EnsureCanContainNonSmiElements(js_object);
+ }
+ }
+
return object;
}
@@ -1631,6 +1660,19 @@ RUNTIME_FUNCTION(MaybeObject*,
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
+ if (FLAG_smi_only_arrays && object->HasFastSmiOnlyElements()) {
+ MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
+ Map* map;
+ if (!maybe_map->To<Map>(&map)) return maybe_map;
+ object->set_map(Map::cast(map));
+ }
+ return *object;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
@@ -2214,7 +2256,8 @@ class FixedArrayBuilder {
public:
explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
: array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
- length_(0) {
+ length_(0),
+ has_non_smi_elements_(false) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
ASSERT(initial_capacity > 0);
@@ -2222,7 +2265,8 @@ class FixedArrayBuilder {
explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
: array_(backing_store),
- length_(0) {
+ length_(0),
+ has_non_smi_elements_(false) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
ASSERT(backing_store->length() > 0);
@@ -2250,12 +2294,15 @@ class FixedArrayBuilder {
}
void Add(Object* value) {
+ ASSERT(!value->IsSmi());
ASSERT(length_ < capacity());
array_->set(length_, value);
length_++;
+ has_non_smi_elements_ = true;
}
void Add(Smi* value) {
+ ASSERT(value->IsSmi());
ASSERT(length_ < capacity());
array_->set(length_, value);
length_++;
@@ -2280,7 +2327,7 @@ class FixedArrayBuilder {
}
Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
- target_array->set_elements(*array_);
+ FACTORY->SetContent(target_array, array_);
target_array->set_length(Smi::FromInt(length_));
return target_array;
}
@@ -2288,6 +2335,7 @@ class FixedArrayBuilder {
private:
Handle<FixedArray> array_;
int length_;
+ bool has_non_smi_elements_;
};
@@ -6121,6 +6169,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
int part_count = indices.length();
Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
+ MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements();
+ if (maybe_result->IsFailure()) return maybe_result;
result->set_length(Smi::FromInt(part_count));
ASSERT(result->HasFastElements());
@@ -6495,6 +6545,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
// This assumption is used by the slice encoding in one or two smis.
ASSERT(Smi::kMaxValue >= String::kMaxLength);
+ MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements();
+ if (maybe_result->IsFailure()) return maybe_result;
+
int special_length = special->length();
if (!array->HasFastElements()) {
return isolate->Throw(isolate->heap()->illegal_argument_symbol());
@@ -6722,7 +6775,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
CONVERT_CHECKED(JSArray, elements_array, args[0]);
- RUNTIME_ASSERT(elements_array->HasFastElements());
+ RUNTIME_ASSERT(elements_array->HasFastElements() ||
+ elements_array->HasFastSmiOnlyElements());
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
CONVERT_CHECKED(String, separator, args[2]);
// elements_array is fast-mode JSarray of alternating positions
@@ -7889,7 +7943,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
int bound_argc = 0;
if (!args[1]->IsNull()) {
CONVERT_ARG_CHECKED(JSArray, params, 1);
- RUNTIME_ASSERT(params->HasFastElements());
+ RUNTIME_ASSERT(params->HasFastTypeElements());
bound_args = Handle<FixedArray>(FixedArray::cast(params->elements()));
bound_argc = Smi::cast(params->length())->value();
}
@@ -8984,6 +9038,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
FlattenString(str);
CONVERT_ARG_CHECKED(JSArray, output, 1);
+
+ MaybeObject* maybe_result_array =
+ output->EnsureCanContainNonSmiElements();
+ if (maybe_result_array->IsFailure()) return maybe_result_array;
RUNTIME_ASSERT(output->HasFastElements());
AssertNoAllocation no_allocation;
@@ -9287,7 +9345,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
ASSERT(args.length() == 2);
CONVERT_CHECKED(JSArray, array, args[0]);
CONVERT_CHECKED(JSObject, element, args[1]);
- RUNTIME_ASSERT(array->HasFastElements());
+ RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
int length = Smi::cast(array->length())->value();
FixedArray* elements = FixedArray::cast(array->elements());
for (int i = 0; i < length; i++) {
@@ -9518,6 +9576,7 @@ static void CollectElementIndices(Handle<JSObject> object,
List<uint32_t>* indices) {
ElementsKind kind = object->GetElementsKind();
switch (kind) {
+ case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(object->elements()));
uint32_t length = static_cast<uint32_t>(elements->length());
@@ -9637,6 +9696,7 @@ static bool IterateElements(Isolate* isolate,
ArrayConcatVisitor* visitor) {
uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
switch (receiver->GetElementsKind()) {
+ case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
// Run through the elements FixedArray and use HasElement and GetElement
// to check the prototype for missing elements.
@@ -9960,7 +10020,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
}
return *isolate->factory()->NewJSArrayWithElements(keys);
} else {
- ASSERT(array->HasFastElements() || array->HasFastDoubleElements());
+ ASSERT(array->HasFastElements() ||
+ array->HasFastSmiOnlyElements() ||
+ array->HasFastDoubleElements());
Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
// -1 means start of array.
single_interval->set(0, Smi::FromInt(-1));
@@ -11870,7 +11932,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
// Return result as a JS array.
Handle<JSObject> result =
isolate->factory()->NewJSObject(isolate->array_function());
- Handle<JSArray>::cast(result)->SetContent(*instances);
+ isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
return *result;
}
@@ -11998,12 +12060,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Return result as JS array.
Object* result;
- { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
+ MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
isolate->context()->global_context()->array_function());
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- JSArray::cast(result)->SetContent(instances);
- return result;
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ return JSArray::cast(result)->SetContent(instances);
}
@@ -12084,8 +12144,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
isolate->context()->global_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- JSArray::cast(result)->SetContent(instances);
- return result;
+ return JSArray::cast(result)->SetContent(instances);
}
@@ -13057,6 +13116,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
return isolate->heap()->ToBoolean(obj->Has##Name()); \
}
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
« src/bootstrapper.cc ('K') | « src/runtime.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698