summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/v8/src/arm/stub-cache-arm.cc
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2012-06-13 09:21:17 +0200
committerQt by Nokia <qt-info@nokia.com>2012-06-13 09:55:50 +0200
commitd47c4a1dad750d278bcf00b630af69c4b8bdb97f (patch)
tree289865bd448633ffec5e8d7e85436b6c0a8a6cad /src/3rdparty/v8/src/arm/stub-cache-arm.cc
parent28017b45db578180d0d54e67aea209ad95f73b9f (diff)
Updated V8 from git://github.com/v8/v8.git to 3e6ec7e018bbf2c63ef04b85ff688198ea204c04
Update V8 source to version 3.11.4 * Performance and stability improvements on all platforms. * Fixed native ARM build (issues 1744, 539) * Fixed several bugs in heap profiles (including issue 2078). * Throw syntax errors on illegal escape sequences. * Made handling of const more consistent when combined with 'eval' and 'with'. * Fixed V8 on MinGW-x64 (issue 2026). * Put new global var semantics behind a flag until WebKit tests are cleaned up. * Enabled inlining some V8 API functions. * Enabled MIPS cross-compilation. * Implemented clearing of CompareICs (issue 2102). * Fixed python deprecations. (issue 1391) * Fixed GCC 4.7 (C++11) compilation. (issue 2136) Change-Id: I72594bd22356391dd55e315c022d0c9f3fd5b451 Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src/3rdparty/v8/src/arm/stub-cache-arm.cc')
-rw-r--r--src/3rdparty/v8/src/arm/stub-cache-arm.cc135
1 files changed, 96 insertions, 39 deletions
diff --git a/src/3rdparty/v8/src/arm/stub-cache-arm.cc b/src/3rdparty/v8/src/arm/stub-cache-arm.cc
index cfd93bc..49c0982 100644
--- a/src/3rdparty/v8/src/arm/stub-cache-arm.cc
+++ b/src/3rdparty/v8/src/arm/stub-cache-arm.cc
@@ -443,8 +443,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
Label exit;
// Check that the map of the object hasn't changed.
+ CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
+ : REQUIRE_EXACT_MAP;
__ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label,
- DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+ DO_SMI_CHECK, mode);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -580,6 +582,8 @@ static void PushInterceptorArguments(MacroAssembler* masm,
__ push(holder);
__ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
__ push(scratch);
+ __ mov(scratch, Operand(ExternalReference::isolate_address()));
+ __ push(scratch);
}
@@ -594,7 +598,7 @@ static void CompileCallLoadPropertyWithInterceptor(
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate());
- __ mov(r0, Operand(5));
+ __ mov(r0, Operand(6));
__ mov(r1, Operand(ref));
CEntryStub stub(1);
@@ -602,9 +606,9 @@ static void CompileCallLoadPropertyWithInterceptor(
}
-static const int kFastApiCallArguments = 3;
+static const int kFastApiCallArguments = 4;
-// Reserves space for the extra arguments to FastHandleApiCall in the
+// Reserves space for the extra arguments to API function in the
// caller's frame.
//
// These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
@@ -630,7 +634,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// -- sp[0] : holder (set by CheckPrototypes)
// -- sp[4] : callee JS function
// -- sp[8] : call data
- // -- sp[12] : last JS argument
+ // -- sp[12] : isolate
+ // -- sp[16] : last JS argument
// -- ...
// -- sp[(argc + 3) * 4] : first JS argument
// -- sp[(argc + 4) * 4] : receiver
@@ -640,7 +645,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
__ LoadHeapObject(r5, function);
__ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
- // Pass the additional arguments FastHandleApiCall expects.
+ // Pass the additional arguments.
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
Handle<Object> call_data(api_call_info->data());
if (masm->isolate()->heap()->InNewSpace(*call_data)) {
@@ -649,13 +654,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
} else {
__ Move(r6, call_data);
}
- // Store JS function and call data.
- __ stm(ib, sp, r5.bit() | r6.bit());
+ __ mov(r7, Operand(ExternalReference::isolate_address()));
+ // Store JS function, call data and isolate.
+ __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
- // r2 points to call data as expected by Arguments
- // (refer to layout above).
- __ add(r2, sp, Operand(2 * kPointerSize));
+ // Prepare arguments.
+ __ add(r2, sp, Operand(3 * kPointerSize));
+ // Allocate the v8::Arguments structure in the arguments' space since
+ // it's not controlled by GC.
const int kApiStackSpace = 4;
FrameScope frame_scope(masm, StackFrame::MANUAL);
@@ -664,9 +671,9 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// r0 = v8::Arguments&
// Arguments is after the return address.
__ add(r0, sp, Operand(1 * kPointerSize));
- // v8::Arguments::implicit_args = data
+ // v8::Arguments::implicit_args_
__ str(r2, MemOperand(r0, 0 * kPointerSize));
- // v8::Arguments::values = last argument
+ // v8::Arguments::values_
__ add(ip, r2, Operand(argc * kPointerSize));
__ str(ip, MemOperand(r0, 1 * kPointerSize));
// v8::Arguments::length_ = argc
@@ -843,7 +850,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ CallExternalReference(
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
masm->isolate()),
- 5);
+ 6);
// Restore the name_ register.
__ pop(name_);
// Leave the internal frame.
@@ -1202,7 +1209,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
} else {
__ Move(scratch3, Handle<Object>(callback->data()));
}
- __ Push(reg, scratch3, name_reg);
+ __ Push(reg, scratch3);
+ __ mov(scratch3, Operand(ExternalReference::isolate_address()));
+ __ Push(scratch3, name_reg);
__ mov(r0, sp); // r0 = Handle<String>
const int kApiStackSpace = 1;
@@ -1214,7 +1223,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ str(scratch2, MemOperand(sp, 1 * kPointerSize));
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo&
- const int kStackUnwindSpace = 4;
+ const int kStackUnwindSpace = 5;
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
ExternalReference ref =
@@ -1264,12 +1273,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
name, miss);
ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
+ // Preserve the receiver register explicitly whenever it is different from
+ // the holder and it is needed should the interceptor return without any
+ // result. The CALLBACKS case needs the receiver to be passed into C++ code,
+ // the FIELD case might cause a miss during the prototype check.
+ bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
+ bool must_preserve_receiver_reg = !receiver.is(holder_reg) &&
+ (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+
// Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers.
{
FrameScope frame_scope(masm(), StackFrame::INTERNAL);
- if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
- // CALLBACKS case needs a receiver to be passed into C++ callback.
+ if (must_preserve_receiver_reg) {
__ Push(receiver, holder_reg, name_reg);
} else {
__ Push(holder_reg, name_reg);
@@ -1294,14 +1310,14 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
__ bind(&interceptor_failed);
__ pop(name_reg);
__ pop(holder_reg);
- if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+ if (must_preserve_receiver_reg) {
__ pop(receiver);
}
// Leave the internal frame.
}
// Check that the maps from interceptor's holder to lookup's holder
// haven't changed. And load lookup's holder into |holder| register.
- if (*interceptor_holder != lookup->holder()) {
+ if (must_perfrom_prototype_check) {
holder_reg = CheckPrototypes(interceptor_holder,
holder_reg,
Handle<JSObject>(lookup->holder()),
@@ -1335,20 +1351,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
if (!receiver.is(holder_reg)) {
ASSERT(scratch1.is(holder_reg));
__ Push(receiver, holder_reg);
- __ ldr(scratch3,
- FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
- __ Push(scratch3, scratch2, name_reg);
} else {
__ push(receiver);
- __ ldr(scratch3,
- FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
- __ Push(holder_reg, scratch3, scratch2, name_reg);
+ __ push(holder_reg);
}
+ __ ldr(scratch3,
+ FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
+ __ mov(scratch1, Operand(ExternalReference::isolate_address()));
+ __ Push(scratch3, scratch1, scratch2, name_reg);
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
masm()->isolate());
- __ TailCallExternalReference(ref, 5, 1);
+ __ TailCallExternalReference(ref, 6, 1);
}
} else { // !compile_followup_inline
// Call the runtime system to load the interceptor.
@@ -1362,7 +1377,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
masm()->isolate());
- __ TailCallExternalReference(ref, 5, 1);
+ __ TailCallExternalReference(ref, 6, 1);
}
}
@@ -3368,6 +3383,44 @@ static bool IsElementTypeSigned(ElementsKind elements_kind) {
}
+static void GenerateSmiKeyCheck(MacroAssembler* masm,
+ Register key,
+ Register scratch0,
+ Register scratch1,
+ DwVfpRegister double_scratch0,
+ Label* fail) {
+ if (CpuFeatures::IsSupported(VFP3)) {
+ CpuFeatures::Scope scope(VFP3);
+ Label key_ok;
+ // Check for smi or a smi inside a heap number. We convert the heap
+ // number and check if the conversion is exact and fits into the smi
+ // range.
+ __ JumpIfSmi(key, &key_ok);
+ __ CheckMap(key,
+ scratch0,
+ Heap::kHeapNumberMapRootIndex,
+ fail,
+ DONT_DO_SMI_CHECK);
+ __ sub(ip, key, Operand(kHeapObjectTag));
+ __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
+ __ EmitVFPTruncate(kRoundToZero,
+ double_scratch0.low(),
+ double_scratch0,
+ scratch0,
+ scratch1,
+ kCheckForInexactConversion);
+ __ b(ne, fail);
+ __ vmov(scratch0, double_scratch0.low());
+ __ TrySmiTag(scratch0, fail, scratch1);
+ __ mov(key, scratch0);
+ __ bind(&key_ok);
+ } else {
+ // Check that the key is a smi.
+ __ JumpIfNotSmi(key, fail);
+ }
+}
+
+
void KeyedLoadStubCompiler::GenerateLoadExternalArray(
MacroAssembler* masm,
ElementsKind elements_kind) {
@@ -3384,8 +3437,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- // Check that the key is a smi.
- __ JumpIfNotSmi(key, &miss_force_generic);
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
__ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
// r3: elements array
@@ -3715,8 +3768,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- // Check that the key is a smi.
- __ JumpIfNotSmi(key, &miss_force_generic);
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
__ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
@@ -4041,8 +4094,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- // Check that the key is a smi.
- __ JumpIfNotSmi(r0, &miss_force_generic);
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, r0, r4, r5, d1, &miss_force_generic);
// Get the elements array.
__ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
@@ -4093,8 +4146,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- // Check that the key is a smi.
- __ JumpIfNotSmi(key_reg, &miss_force_generic);
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
// Get the elements array.
__ ldr(elements_reg,
@@ -4169,8 +4222,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- // Check that the key is a smi.
- __ JumpIfNotSmi(key_reg, &miss_force_generic);
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
__ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4336,7 +4389,9 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+ // Check that the key is a smi or a heap number convertible to a smi.
+ GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
__ ldr(elements_reg,
FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
@@ -4427,6 +4482,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
// Increment the length of the array.
__ mov(length_reg, Operand(Smi::FromInt(1)));
__ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+ __ ldr(elements_reg,
+ FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
__ jmp(&finish_store);
__ bind(&check_capacity);