Commit e1b84ed2 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

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

  port aafc3e54 (r32926)

  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.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#32937}
parent 0794c3c9
......@@ -2724,26 +2724,11 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
DCHECK(!temp.is(temp2));
__ JumpIfSmi(input, is_false);
__ CmpObjectType(input, JS_FUNCTION_TYPE, temp);
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);
__ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp);
__ j(below, is_false);
__ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE);
__ j(equal, 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.
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
__ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
__ sub(Operand(temp2), Immediate(FIRST_JS_RECEIVER_TYPE));
__ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
FIRST_JS_RECEIVER_TYPE));
__ j(above, is_false);
__ j(equal, is_false);
}
// Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
......
......@@ -3117,7 +3117,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
&if_false, &fall_through);
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, JS_PROXY_TYPE, ebx);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
......@@ -3196,49 +3195,40 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
// If the object is a smi, we return null.
__ JumpIfSmi(eax, &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);
// If the object is not a JSReceiver, we return null.
__ JumpIfSmi(eax, &null, Label::kNear);
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, eax);
// Map is now in eax.
__ j(below, &null);
__ j(below, &null, Label::kNear);
__ CmpInstanceType(eax, LAST_JS_RECEIVER_TYPE);
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
LAST_JS_RECEIVER_TYPE - 1);
__ j(equal, &function);
// Assume that there is no larger type.
STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
// Return 'Function' for JSFunction objects.
__ CmpInstanceType(eax, JS_FUNCTION_TYPE);
__ j(equal, &function, Label::kNear);
// Check if the constructor in the map is a JS function.
__ GetMapConstructor(eax, eax, ebx);
__ CmpInstanceType(ebx, JS_FUNCTION_TYPE);
__ j(not_equal, &non_function_constructor);
__ j(not_equal, &non_function_constructor, Label::kNear);
// eax now contains the constructor function. Grab the
// instance class name from there.
__ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
__ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Non-JS objects have class null.
__ bind(&null);
__ mov(eax, isolate()->factory()->null_value());
__ jmp(&done, Label::kNear);
// Functions have class 'Function'.
__ bind(&function);
__ mov(eax, isolate()->factory()->Function_string());
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Objects with a non-function constructor have class 'Object'.
__ bind(&non_function_constructor);
__ mov(eax, isolate()->factory()->Object_string());
__ jmp(&done);
// Non-JS objects have class null.
__ bind(&null);
__ mov(eax, isolate()->factory()->null_value());
// All done.
__ bind(&done);
......
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