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

Unified Diff: src/builtins.cc

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 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
« no previous file with comments | « src/builtins.h ('k') | src/cached-powers.h » ('j') | src/heap.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
===================================================================
--- src/builtins.cc (revision 4205)
+++ src/builtins.cc (working copy)
@@ -319,6 +319,24 @@
}
+static bool IsJSArrayWithFastElements(Object* receiver,
+ FixedArray** elements) {
+ if (!receiver->IsJSArray()) {
+ return false;
+ }
+
+ JSArray* array = JSArray::cast(receiver);
+
+ HeapObject* elms = HeapObject::cast(array->elements());
+ if (elms->map() != Heap::fixed_array_map()) {
+ return false;
+ }
+
+ *elements = FixedArray::cast(elms);
+ return true;
+}
+
+
static Object* CallJsBuiltin(const char* name,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
HandleScope handleScope;
@@ -331,7 +349,7 @@
Vector<Object**> argv(Vector<Object**>::New(args.length() - 1));
int n_args = args.length() - 1;
for (int i = 0; i < n_args; i++) {
- argv[i] = &args[i + 1];
+ argv[i] = args.at<Object>(i + 1).location();
}
bool pending_exception = false;
Handle<Object> result = Execution::Call(function,
@@ -346,8 +364,12 @@
BUILTIN(ArrayPush) {
- JSArray* array = JSArray::cast(*args.receiver());
- ASSERT(array->HasFastElements());
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)) {
+ return CallJsBuiltin("ArrayPush", args);
+ }
+ JSArray* array = JSArray::cast(receiver);
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
@@ -359,7 +381,6 @@
ASSERT(to_add <= (Smi::kMaxValue - len));
int new_length = len + to_add;
- FixedArray* elms = FixedArray::cast(array->elements());
if (new_length > elms->length()) {
// New backing storage is needed.
@@ -390,14 +411,17 @@
BUILTIN(ArrayPop) {
- JSArray* array = JSArray::cast(*args.receiver());
- ASSERT(array->HasFastElements());
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)) {
+ return CallJsBuiltin("ArrayPop", args);
+ }
+ JSArray* array = JSArray::cast(receiver);
int len = Smi::cast(array->length())->value();
if (len == 0) return Heap::undefined_value();
// Get top element
- FixedArray* elms = FixedArray::cast(array->elements());
Object* top = elms->get(len - 1);
// Set the length.
@@ -420,18 +444,18 @@
BUILTIN(ArrayShift) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArrayShift", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
if (len == 0) return Heap::undefined_value();
- FixedArray* elms = FixedArray::cast(array->elements());
-
// Get first element
Object* first = elms->get(0);
if (first->IsTheHole()) {
@@ -451,26 +475,22 @@
BUILTIN(ArrayUnshift) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArrayUnshift", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
- // Note that we cannot quit early if to_add == 0 as
- // values should be lifted from prototype into
- // the array.
-
int new_length = len + to_add;
// Currently fixed arrays cannot grow too big, so
// we should never hit this case.
ASSERT(to_add <= (Smi::kMaxValue - len));
- FixedArray* elms = FixedArray::cast(array->elements());
-
if (new_length > elms->length()) {
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
@@ -503,11 +523,13 @@
BUILTIN(ArraySlice) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArraySlice", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
@@ -558,8 +580,6 @@
if (result->IsFailure()) return result;
FixedArray* result_elms = FixedArray::cast(result);
- FixedArray* elms = FixedArray::cast(array->elements());
-
AssertNoAllocation no_gc;
CopyElements(&no_gc, result_elms, 0, elms, k, result_len);
@@ -573,11 +593,13 @@
BUILTIN(ArraySplice) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArraySplice", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
@@ -618,8 +640,6 @@
}
int actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
- FixedArray* elms = FixedArray::cast(array->elements());
-
JSArray* result_array = NULL;
if (actual_delete_count == 0) {
Object* result = AllocateEmptyJSArray();
@@ -707,6 +727,68 @@
}
+BUILTIN(ArrayConcat) {
+ if (!ArrayPrototypeHasNoElements()) {
+ return CallJsBuiltin("ArrayConcat", args);
+ }
+
+ // Iterate through all the arguments performing checks
+ // and calculating total length.
+ int n_arguments = args.length();
+ int result_len = 0;
+ for (int i = 0; i < n_arguments; i++) {
+ Object* arg = args[i];
+ if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements()) {
+ return CallJsBuiltin("ArrayConcat", args);
+ }
+
+ int len = Smi::cast(JSArray::cast(arg)->length())->value();
+
+ // We shouldn't overflow when adding another len.
+ const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
+ STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
+ USE(kHalfOfMaxInt);
+ result_len += len;
+ ASSERT(result_len >= 0);
+
+ if (result_len > FixedArray::kMaxLength) {
+ return CallJsBuiltin("ArrayConcat", args);
+ }
+ }
+
+ if (result_len == 0) {
+ return AllocateEmptyJSArray();
+ }
+
+ // Allocate result.
+ Object* result = AllocateJSArray();
+ if (result->IsFailure()) return result;
+ JSArray* result_array = JSArray::cast(result);
+
+ result = Heap::AllocateUninitializedFixedArray(result_len);
+ if (result->IsFailure()) return result;
+ FixedArray* result_elms = FixedArray::cast(result);
+
+ // Copy data.
+ AssertNoAllocation no_gc;
+ int start_pos = 0;
+ for (int i = 0; i < n_arguments; i++) {
+ JSArray* array = JSArray::cast(args[i]);
+ FixedArray* elms = FixedArray::cast(array->elements());
+ int len = Smi::cast(array->length())->value();
+ CopyElements(&no_gc, result_elms, start_pos, elms, 0, len);
+ start_pos += len;
+ }
+ ASSERT(start_pos == result_len);
+
+ // Set the length and elements.
+ result_array->set_length(Smi::FromInt(result_len));
+ result_array->set_elements(result_elms);
+
+ return result_array;
+}
+
+
// -----------------------------------------------------------------------------
//
@@ -766,20 +848,19 @@
HandleScope scope;
Handle<JSFunction> function = args.called_function();
+ ASSERT(function->shared()->IsApiFunction());
+ FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
if (is_construct) {
- Handle<FunctionTemplateInfo> desc =
- Handle<FunctionTemplateInfo>(
- FunctionTemplateInfo::cast(function->shared()->function_data()));
+ Handle<FunctionTemplateInfo> desc(fun_data);
bool pending_exception = false;
Factory::ConfigureInstance(desc, Handle<JSObject>::cast(args.receiver()),
&pending_exception);
ASSERT(Top::has_pending_exception() == pending_exception);
if (pending_exception) return Failure::Exception();
+ fun_data = *desc;
}
- FunctionTemplateInfo* fun_data =
- FunctionTemplateInfo::cast(function->shared()->function_data());
Object* raw_holder = TypeCheck(args.length(), &args[0], fun_data);
if (raw_holder->IsNull()) {
@@ -850,8 +931,8 @@
static void VerifyTypeCheck(Handle<JSObject> object,
Handle<JSFunction> function) {
- FunctionTemplateInfo* info =
- FunctionTemplateInfo::cast(function->shared()->function_data());
+ ASSERT(function->shared()->IsApiFunction());
+ FunctionTemplateInfo* info = function->shared()->get_api_func_data();
if (info->signature()->IsUndefined()) return;
SignatureInfo* signature = SignatureInfo::cast(info->signature());
Object* receiver_type = signature->receiver();
@@ -935,9 +1016,9 @@
// used to create the called object.
ASSERT(obj->map()->has_instance_call_handler());
JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
- Object* template_info = constructor->shared()->function_data();
+ ASSERT(constructor->shared()->IsApiFunction());
Object* handler =
- FunctionTemplateInfo::cast(template_info)->instance_call_handler();
+ constructor->shared()->get_api_func_data()->instance_call_handler();
ASSERT(!handler->IsUndefined());
CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
Object* callback_obj = call_data->callback();
« no previous file with comments | « src/builtins.h ('k') | src/cached-powers.h » ('j') | src/heap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698