From: verwaest@chromium.org Date: Wed, 23 Jul 2014 11:12:11 +0000 (+0000) Subject: Only to the relevant checks in LoadFunctionPrototype X-Git-Tag: upstream/4.7.83~8095 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8eb36a9342b4f6631c2227ff101558e928b4598;p=platform%2Fupstream%2Fv8.git Only to the relevant checks in LoadFunctionPrototype BUG= R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/412483003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22550 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 71f727a..b8cae01 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -2283,14 +2283,15 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register scratch, Label* miss, bool miss_on_bound_function) { - // Check that the receiver isn't a smi. - JumpIfSmi(function, miss); + Label non_instance; + if (miss_on_bound_function) { + // Check that the receiver isn't a smi. + JumpIfSmi(function, miss); - // Check that the function really is a function. Load map into result reg. - CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE); - b(ne, miss); + // Check that the function really is a function. Load map into result reg. + CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE); + b(ne, miss); - if (miss_on_bound_function) { ldr(scratch, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); ldr(scratch, @@ -2298,13 +2299,12 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, tst(scratch, Operand(Smi::FromInt(1 << SharedFunctionInfo::kBoundFunction))); b(ne, miss); - } - // Make sure that the function has an instance prototype. - Label non_instance; - ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); - tst(scratch, Operand(1 << Map::kHasNonInstancePrototype)); - b(ne, &non_instance); + // Make sure that the function has an instance prototype. + ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); + tst(scratch, Operand(1 << Map::kHasNonInstancePrototype)); + b(ne, &non_instance); + } // Get the prototype or initial map from the function. ldr(result, @@ -2324,12 +2324,15 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, // Get the prototype from the initial map. ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); - jmp(&done); - // Non-instance prototype: Fetch prototype from constructor field - // in initial map. - bind(&non_instance); - ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); + if (miss_on_bound_function) { + jmp(&done); + + // Non-instance prototype: Fetch prototype from constructor field + // in initial map. + bind(&non_instance); + ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); + } // All done. bind(&done); diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc index ff5efd5..083f774 100644 --- a/src/arm64/macro-assembler-arm64.cc +++ b/src/arm64/macro-assembler-arm64.cc @@ -3816,13 +3816,14 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, BoundFunctionAction action) { ASSERT(!AreAliased(function, result, scratch)); - // Check that the receiver isn't a smi. - JumpIfSmi(function, miss); + Label non_instance; + if (action == kMissOnBoundFunction) { + // Check that the receiver isn't a smi. + JumpIfSmi(function, miss); - // Check that the function really is a function. Load map into result reg. - JumpIfNotObjectType(function, result, scratch, JS_FUNCTION_TYPE, miss); + // Check that the function really is a function. Load map into result reg. + JumpIfNotObjectType(function, result, scratch, JS_FUNCTION_TYPE, miss); - if (action == kMissOnBoundFunction) { Register scratch_w = scratch.W(); Ldr(scratch, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); @@ -3831,12 +3832,11 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Ldr(scratch_w, FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); Tbnz(scratch, SharedFunctionInfo::kBoundFunction, miss); - } - // Make sure that the function has an instance prototype. - Label non_instance; - Ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); - Tbnz(scratch, Map::kHasNonInstancePrototype, &non_instance); + // Make sure that the function has an instance prototype. + Ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); + Tbnz(scratch, Map::kHasNonInstancePrototype, &non_instance); + } // Get the prototype or initial map from the function. Ldr(result, @@ -3853,12 +3853,15 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, // Get the prototype from the initial map. Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); - B(&done); - // Non-instance prototype: fetch prototype from constructor field in initial - // map. - Bind(&non_instance); - Ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); + if (action == kMissOnBoundFunction) { + B(&done); + + // Non-instance prototype: fetch prototype from constructor field in initial + // map. + Bind(&non_instance); + Ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); + } // All done. Bind(&done); diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index e9920b5..395e824 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1976,27 +1976,27 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register scratch, Label* miss, bool miss_on_bound_function) { - // Check that the receiver isn't a smi. - JumpIfSmi(function, miss); + Label non_instance; + if (miss_on_bound_function) { + // Check that the receiver isn't a smi. + JumpIfSmi(function, miss); - // Check that the function really is a function. - CmpObjectType(function, JS_FUNCTION_TYPE, result); - j(not_equal, miss); + // Check that the function really is a function. + CmpObjectType(function, JS_FUNCTION_TYPE, result); + j(not_equal, miss); - if (miss_on_bound_function) { // If a bound function, go to miss label. mov(scratch, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); BooleanBitTest(scratch, SharedFunctionInfo::kCompilerHintsOffset, SharedFunctionInfo::kBoundFunction); j(not_zero, miss); - } - // Make sure that the function has an instance prototype. - Label non_instance; - movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); - test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); - j(not_zero, &non_instance); + // Make sure that the function has an instance prototype. + movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); + test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); + j(not_zero, &non_instance); + } // Get the prototype or initial map from the function. mov(result, @@ -2015,12 +2015,15 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, // Get the prototype from the initial map. mov(result, FieldOperand(result, Map::kPrototypeOffset)); - jmp(&done); - // Non-instance prototype: Fetch prototype from constructor field - // in initial map. - bind(&non_instance); - mov(result, FieldOperand(result, Map::kConstructorOffset)); + if (miss_on_bound_function) { + jmp(&done); + + // Non-instance prototype: Fetch prototype from constructor field + // in initial map. + bind(&non_instance); + mov(result, FieldOperand(result, Map::kConstructorOffset)); + } // All done. bind(&done); diff --git a/src/ic.cc b/src/ic.cc index 0910ae8..e7ece5d 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -937,7 +937,8 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, Handle object, // Use specialized code for getting prototype of functions. if (object->IsJSFunction() && String::Equals(isolate()->factory()->prototype_string(), name) && - Handle::cast(object)->should_have_prototype()) { + Handle::cast(object)->should_have_prototype() && + !Handle::cast(object)->map()->has_non_instance_prototype()) { Handle stub; FunctionPrototypeStub function_prototype_stub(isolate(), kind()); return function_prototype_stub.GetCode(); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index a5e2972..079f9b0 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -3745,15 +3745,16 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, Label* miss, bool miss_on_bound_function) { - // Check that the receiver isn't a smi. - testl(function, Immediate(kSmiTagMask)); - j(zero, miss); + Label non_instance; + if (miss_on_bound_function) { + // Check that the receiver isn't a smi. + testl(function, Immediate(kSmiTagMask)); + j(zero, miss); - // Check that the function really is a function. - CmpObjectType(function, JS_FUNCTION_TYPE, result); - j(not_equal, miss); + // Check that the function really is a function. + CmpObjectType(function, JS_FUNCTION_TYPE, result); + j(not_equal, miss); - if (miss_on_bound_function) { movp(kScratchRegister, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); // It's not smi-tagged (stored in the top half of a smi-tagged 8-byte @@ -3762,13 +3763,12 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, SharedFunctionInfo::kCompilerHintsOffset, SharedFunctionInfo::kBoundFunction); j(not_zero, miss); - } - // Make sure that the function has an instance prototype. - Label non_instance; - testb(FieldOperand(result, Map::kBitFieldOffset), - Immediate(1 << Map::kHasNonInstancePrototype)); - j(not_zero, &non_instance, Label::kNear); + // Make sure that the function has an instance prototype. + testb(FieldOperand(result, Map::kBitFieldOffset), + Immediate(1 << Map::kHasNonInstancePrototype)); + j(not_zero, &non_instance, Label::kNear); + } // Get the prototype or initial map from the function. movp(result, @@ -3787,12 +3787,15 @@ void MacroAssembler::TryGetFunctionPrototype(Register function, // Get the prototype from the initial map. movp(result, FieldOperand(result, Map::kPrototypeOffset)); - jmp(&done, Label::kNear); - // Non-instance prototype: Fetch prototype from constructor field - // in initial map. - bind(&non_instance); - movp(result, FieldOperand(result, Map::kConstructorOffset)); + if (miss_on_bound_function) { + jmp(&done, Label::kNear); + + // Non-instance prototype: Fetch prototype from constructor field + // in initial map. + bind(&non_instance); + movp(result, FieldOperand(result, Map::kConstructorOffset)); + } // All done. bind(&done);