Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Upgrade V8 to 3.8.4

  • Loading branch information...
ry committed Jan 3, 2012
1 parent c123ac0 commit 557fc396b4f5c165de90fbf9eaecb4370b46c057
@@ -1,3 +1,10 @@
2012-01-02: Version 3.8.4

Performance improvements for large Smi-only arrays.

Fixed InternalArrays construction. (issue 1878)


2011-12-27: Version 3.8.3

Avoid embedding new space objects into code objects in the lithium gap
@@ -72,6 +72,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
}


// Load the built-in InternalArray function from the current context.
static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
Register result) {
// Load the global context.

__ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ ldr(result,
FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
// Load the InternalArray function from the global context.
__ ldr(result,
MemOperand(result,
Context::SlotOffset(
Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
}


// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the global context.
@@ -418,6 +434,40 @@ static void ArrayNativeCode(MacroAssembler* masm,
}


void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : number of arguments
// -- lr : return address
// -- sp[...]: constructor arguments
// -----------------------------------
Label generic_array_code, one_or_more_arguments, two_or_more_arguments;

// Get the InternalArray function.
GenerateLoadInternalArrayFunction(masm, r1);

if (FLAG_debug_code) {
// Initial map for the builtin InternalArray functions should be maps.
__ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
__ tst(r2, Operand(kSmiTagMask));
__ Assert(ne, "Unexpected initial map for InternalArray function");
__ CompareObjectType(r2, r3, r4, MAP_TYPE);
__ Assert(eq, "Unexpected initial map for InternalArray function");
}

// Run the native code for the InternalArray function called as a normal
// function.
ArrayNativeCode(masm, &generic_array_code);

// Jump to the generic array code if the specialized code cannot handle the
// construction.
__ bind(&generic_array_code);

Handle<Code> array_code =
masm->isolate()->builtins()->InternalArrayCodeGeneric();
__ Jump(array_code, RelocInfo::CODE_TARGET);
}


void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : number of arguments
@@ -748,7 +748,8 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
type->LookupInDescriptors(NULL, *name, &lookup);
// If the function wasn't found directly in the map, we start
// looking upwards through the prototype chain.
if (!lookup.IsFound() && type->prototype()->IsJSObject()) {
if ((!lookup.IsFound() || IsTransitionType(lookup.type()))
&& type->prototype()->IsJSObject()) {
holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
type = Handle<Map>(holder()->map());
} else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
@@ -1613,16 +1613,13 @@ bool Genesis::InstallNatives() {
// doesn't inherit from Object.prototype.
// To be used only for internal work by builtins. Instances
// must not be leaked to user code.
// Only works correctly when called as a constructor. The normal
// Array code uses Array.prototype as prototype when called as
// a function.
Handle<JSFunction> array_function =
InstallFunction(builtins,
"InternalArray",
JS_ARRAY_TYPE,
JSArray::kSize,
isolate()->initial_object_prototype(),
Builtins::kArrayCode,
Builtins::kInternalArrayCode,
true);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
@@ -1654,6 +1651,8 @@ bool Genesis::InstallNatives() {

array_function->initial_map()->set_instance_descriptors(
*array_descriptors);

global_context()->set_internal_array_function(*array_function);
}

if (FLAG_disable_native_files) {
@@ -184,31 +184,28 @@ BUILTIN(EmptyFunction) {
}


BUILTIN(ArrayCodeGeneric) {
static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
Isolate* isolate,
JSFunction* constructor) {
Heap* heap = isolate->heap();
isolate->counters()->array_function_runtime()->Increment();

JSArray* array;
if (CalledAsConstructor(isolate)) {
array = JSArray::cast(*args.receiver());
array = JSArray::cast((*args)[0]);
} else {
// Allocate the JS Array
JSFunction* constructor =
isolate->context()->global_context()->array_function();
Object* obj;
{ MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
array = JSArray::cast(obj);
}

// 'array' now contains the JSArray we should initialize.
ASSERT(array->HasFastTypeElements());

// Optimize the case where there is one argument and the argument is a
// small smi.
if (args.length() == 2) {
Object* obj = args[1];
if (args->length() == 2) {
Object* obj = (*args)[1];
if (obj->IsSmi()) {
int len = Smi::cast(obj)->value();
if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
@@ -225,18 +222,18 @@ BUILTIN(ArrayCodeGeneric) {
{ MaybeObject* maybe_obj = array->Initialize(0);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
return array->SetElementsLength(args[1]);
return array->SetElementsLength((*args)[1]);
}

// Optimize the case where there are no parameters passed.
if (args.length() == 1) {
if (args->length() == 1) {
return array->Initialize(JSArray::kPreallocatedArrayElements);
}

// Set length and elements on the array.
int number_of_elements = args.length() - 1;
int number_of_elements = args->length() - 1;
MaybeObject* maybe_object =
array->EnsureCanContainElements(&args, 1, number_of_elements,
array->EnsureCanContainElements(args, 1, number_of_elements,
ALLOW_CONVERTED_DOUBLE_ELEMENTS);
if (maybe_object->IsFailure()) return maybe_object;

@@ -257,7 +254,7 @@ BUILTIN(ArrayCodeGeneric) {
case FAST_SMI_ONLY_ELEMENTS: {
FixedArray* smi_elms = FixedArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
smi_elms->set(index, args[index+1], SKIP_WRITE_BARRIER);
smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER);
}
break;
}
@@ -266,14 +263,14 @@ BUILTIN(ArrayCodeGeneric) {
WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
FixedArray* object_elms = FixedArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
object_elms->set(index, args[index+1], mode);
object_elms->set(index, (*args)[index+1], mode);
}
break;
}
case FAST_DOUBLE_ELEMENTS: {
FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
double_elms->set(index, args[index+1]->Number());
double_elms->set(index, (*args)[index+1]->Number());
}
break;
}
@@ -288,6 +285,22 @@ BUILTIN(ArrayCodeGeneric) {
}


BUILTIN(InternalArrayCodeGeneric) {
return ArrayCodeGenericCommon(
&args,
isolate,
isolate->context()->global_context()->internal_array_function());
}


BUILTIN(ArrayCodeGeneric) {
return ArrayCodeGenericCommon(
&args,
isolate,
isolate->context()->global_context()->array_function());
}


MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) {
JSFunction* array_function =
heap->isolate()->context()->global_context()->array_function();
@@ -44,6 +44,7 @@ enum BuiltinExtraArguments {
\
V(EmptyFunction, NO_EXTRA_ARGUMENTS) \
\
V(InternalArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \
V(ArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \
\
V(ArrayPush, NO_EXTRA_ARGUMENTS) \
@@ -178,6 +179,8 @@ enum BuiltinExtraArguments {
V(FunctionApply, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
\
V(InternalArrayCode, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
V(ArrayCode, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
V(ArrayConstructCode, BUILTIN, UNINITIALIZED, \
@@ -359,6 +362,7 @@ class Builtins {
static void Generate_FunctionCall(MacroAssembler* masm);
static void Generate_FunctionApply(MacroAssembler* masm);

static void Generate_InternalArrayCode(MacroAssembler* masm);
static void Generate_ArrayCode(MacroAssembler* masm);
static void Generate_ArrayConstructCode(MacroAssembler* masm);

@@ -104,6 +104,7 @@ enum BindingFlags {
V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
V(JSON_OBJECT_INDEX, JSObject, json_object) \
@@ -244,6 +245,7 @@ class Context: public FixedArray {
STRING_FUNCTION_INDEX,
STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
OBJECT_FUNCTION_INDEX,
INTERNAL_ARRAY_FUNCTION_INDEX,
ARRAY_FUNCTION_INDEX,
DATE_FUNCTION_INDEX,
JSON_OBJECT_INDEX,
@@ -1308,6 +1308,40 @@ static void ArrayNativeCode(MacroAssembler* masm,
}


void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argc
// -- esp[0] : return address
// -- esp[4] : last argument
// -----------------------------------
Label generic_array_code;

// Get the InternalArray function.
__ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);

if (FLAG_debug_code) {
// Initial map for the builtin InternalArray function shoud be a map.
__ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
__ test(ebx, Immediate(kSmiTagMask));
__ Assert(not_zero, "Unexpected initial map for InternalArray function");
__ CmpObjectType(ebx, MAP_TYPE, ecx);
__ Assert(equal, "Unexpected initial map for InternalArray function");
}

// Run the native code for the InternalArray function called as a normal
// function.
ArrayNativeCode(masm, false, &generic_array_code);

// Jump to the generic array code in case the specialized code cannot handle
// the construction.
__ bind(&generic_array_code);
Handle<Code> array_code =
masm->isolate()->builtins()->InternalArrayCodeGeneric();
__ jmp(array_code, RelocInfo::CODE_TARGET);
}


void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argc
@@ -1219,7 +1219,7 @@ void JSObject::ValidateSmiOnlyElements() {
map != heap->free_space_map()) {
for (int i = 0; i < fixed_array->length(); i++) {
Object* current = fixed_array->get(i);
ASSERT(current->IsSmi() || current == heap->the_hole_value());
ASSERT(current->IsSmi() || current->IsTheHole());
}
}
}
@@ -1290,22 +1290,37 @@ MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
}


void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
void JSObject::set_map_and_elements(Map* new_map,
FixedArrayBase* value,
WriteBarrierMode mode) {
ASSERT(value->HasValidElements());
#ifdef DEBUG
ValidateSmiOnlyElements();
#endif
if (new_map != NULL) {
if (mode == UPDATE_WRITE_BARRIER) {
set_map(new_map);
} else {
ASSERT(mode == SKIP_WRITE_BARRIER);
set_map_no_write_barrier(new_map);
}
}
ASSERT((map()->has_fast_elements() ||
map()->has_fast_smi_only_elements()) ==
(value->map() == GetHeap()->fixed_array_map() ||
value->map() == GetHeap()->fixed_cow_array_map()));
ASSERT(map()->has_fast_double_elements() ==
value->IsFixedDoubleArray());
ASSERT(value->HasValidElements());
#ifdef DEBUG
ValidateSmiOnlyElements();
#endif
WRITE_FIELD(this, kElementsOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
}


void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
set_map_and_elements(NULL, value, mode);
}


void JSObject::initialize_properties() {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());

0 comments on commit 557fc39

Please sign in to comment.
You can’t perform that action at this time.