Commit 5c33ac6c authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [runtime] Drop FIRST/LAST_NONCALLABLE_SPEC_OBJECT instance type range.

Port aafc3e54

Original commit message:
    The FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range was accidentially used
    in field type tracking, where we should check for JSReceiver instead
    (there's no need to exclude JSProxy or JSFunction from tracking).

    And the use in %_ClassOf was actually wrong and didn't match the C++
    implementation in JSReceiver::class_name() anymore. Now it's consistent
    again.

R=bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=chromium:535408
LOG=n

Review URL: https://codereview.chromium.org/1537013002

Cr-Commit-Position: refs/heads/master@{#32973}
parent 98cf7310
......@@ -2610,36 +2610,20 @@ void LCodeGen::EmitClassOfTest(Label* is_true, Label* is_false,
__ JumpIfSmi(input, is_false);
__ CompareObjectType(input, temp, temp2, JS_FUNCTION_TYPE);
if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
// Assuming the following assertions, we can use the same compares to test
// for both being a function type and being in the object type range.
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
LAST_JS_RECEIVER_TYPE - 1);
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CompareObjectType(input, temp, temp2, FIRST_JS_RECEIVER_TYPE);
__ blt(is_false);
__ cmpi(temp2, Operand(LAST_JS_RECEIVER_TYPE));
__ beq(is_true);
} else {
// Faster code path to avoid two compares: subtract lower bound from the
// actual type and do a signed compare with the width of the type range.
__ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset));
__ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset));
__ subi(temp2, temp2, Operand(FIRST_JS_RECEIVER_TYPE));
__ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
FIRST_JS_RECEIVER_TYPE));
__ bgt(is_false);
__ beq(is_false);
}
// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
// Check if the constructor in the map is a function.
Register instance_type = ip;
__ GetMapConstructor(temp, temp, temp2, instance_type);
// Objects with a non-function constructor have class 'Object'.
__ cmpi(instance_type, Operand(JS_FUNCTION_TYPE));
if (class_name->IsOneByteEqualTo(STATIC_CHAR_VECTOR("Object"))) {
if (String::Equals(isolate()->factory()->Object_string(), class_name)) {
__ bne(is_true);
} else {
__ bne(is_false);
......
......@@ -3321,23 +3321,16 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
// If the object is a smi, we return null.
// If the object is not a JSReceiver, we return null.
__ JumpIfSmi(r3, &null);
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
// Assume that there are only two callable types, and one of them is at
// either end of the type range for JS object types. Saves extra comparisons.
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CompareObjectType(r3, r3, r4, FIRST_JS_RECEIVER_TYPE);
// Map is now in r3.
__ blt(&null);
__ cmpi(r4, Operand(LAST_JS_RECEIVER_TYPE));
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_JS_RECEIVER_TYPE - 1);
// Return 'Function' for JSFunction objects.
__ cmpi(r4, Operand(JS_FUNCTION_TYPE));
__ beq(&function);
// Assume that there is no larger type.
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
// Check if the constructor in the map is a JS function.
Register instance_type = r5;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment