| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 if (strlen(FLAG_stop_at) > 0 && | 110 if (strlen(FLAG_stop_at) > 0 && |
| 111 info->literal()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 111 info->literal()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
| 112 __ stop("stop-at"); | 112 __ stop("stop-at"); |
| 113 } | 113 } |
| 114 #endif | 114 #endif |
| 115 | 115 |
| 116 if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) { | 116 if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) { |
| 117 int receiver_offset = info->scope()->num_parameters() * kPointerSize; | 117 int receiver_offset = info->scope()->num_parameters() * kPointerSize; |
| 118 __ LoadP(r5, MemOperand(sp, receiver_offset), r0); | 118 __ LoadP(r5, MemOperand(sp, receiver_offset), r0); |
| 119 __ AssertNotSmi(r5); | 119 __ AssertNotSmi(r5); |
| 120 __ CompareObjectType(r5, r5, no_reg, FIRST_SPEC_OBJECT_TYPE); | 120 __ CompareObjectType(r5, r5, no_reg, FIRST_JS_RECEIVER_TYPE); |
| 121 __ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver); | 121 __ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver); |
| 122 } | 122 } |
| 123 | 123 |
| 124 // Open a frame scope to indicate that there is a frame on the stack. The | 124 // Open a frame scope to indicate that there is a frame on the stack. The |
| 125 // MANUAL indicates that the scope shouldn't actually generate code to set up | 125 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 126 // the frame (that is done below). | 126 // the frame (that is done below). |
| 127 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 127 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 128 int prologue_offset = masm_->pc_offset(); | 128 int prologue_offset = masm_->pc_offset(); |
| 129 | 129 |
| 130 if (prologue_offset) { | 130 if (prologue_offset) { |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 Register null_value = r7; | 998 Register null_value = r7; |
| 999 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 999 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
| 1000 __ cmp(r3, null_value); | 1000 __ cmp(r3, null_value); |
| 1001 __ beq(&exit); | 1001 __ beq(&exit); |
| 1002 | 1002 |
| 1003 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1003 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
| 1004 | 1004 |
| 1005 // Convert the object to a JS object. | 1005 // Convert the object to a JS object. |
| 1006 Label convert, done_convert; | 1006 Label convert, done_convert; |
| 1007 __ JumpIfSmi(r3, &convert); | 1007 __ JumpIfSmi(r3, &convert); |
| 1008 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); | 1008 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); |
| 1009 __ bge(&done_convert); | 1009 __ bge(&done_convert); |
| 1010 __ bind(&convert); | 1010 __ bind(&convert); |
| 1011 ToObjectStub stub(isolate()); | 1011 ToObjectStub stub(isolate()); |
| 1012 __ CallStub(&stub); | 1012 __ CallStub(&stub); |
| 1013 __ bind(&done_convert); | 1013 __ bind(&done_convert); |
| 1014 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); | 1014 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); |
| 1015 __ push(r3); | 1015 __ push(r3); |
| 1016 | 1016 |
| 1017 // Check for proxies. | 1017 // Check for proxies. |
| 1018 Label call_runtime; | 1018 Label call_runtime; |
| 1019 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1019 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
| 1020 __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE); | 1020 __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE); |
| 1021 __ ble(&call_runtime); | 1021 __ ble(&call_runtime); |
| 1022 | 1022 |
| 1023 // Check cache validity in generated code. This is a fast case for | 1023 // Check cache validity in generated code. This is a fast case for |
| 1024 // the JSObject::IsSimpleEnum cache validity checks. If we cannot | 1024 // the JSObject::IsSimpleEnum cache validity checks. If we cannot |
| 1025 // guarantee cache validity, call the runtime system to check cache | 1025 // guarantee cache validity, call the runtime system to check cache |
| 1026 // validity or get the property names in a fixed array. | 1026 // validity or get the property names in a fixed array. |
| 1027 __ CheckEnumCache(null_value, &call_runtime); | 1027 __ CheckEnumCache(null_value, &call_runtime); |
| 1028 | 1028 |
| 1029 // The enum cache is valid. Load the map of the object being | 1029 // The enum cache is valid. Load the map of the object being |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 __ bind(&fixed_array); | 1076 __ bind(&fixed_array); |
| 1077 | 1077 |
| 1078 __ EmitLoadTypeFeedbackVector(r4); | 1078 __ EmitLoadTypeFeedbackVector(r4); |
| 1079 __ mov(r5, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 1079 __ mov(r5, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
| 1080 int vector_index = SmiFromSlot(slot)->value(); | 1080 int vector_index = SmiFromSlot(slot)->value(); |
| 1081 __ StoreP( | 1081 __ StoreP( |
| 1082 r5, FieldMemOperand(r4, FixedArray::OffsetOfElementAt(vector_index)), r0); | 1082 r5, FieldMemOperand(r4, FixedArray::OffsetOfElementAt(vector_index)), r0); |
| 1083 | 1083 |
| 1084 __ LoadSmiLiteral(r4, Smi::FromInt(1)); // Smi indicates slow check | 1084 __ LoadSmiLiteral(r4, Smi::FromInt(1)); // Smi indicates slow check |
| 1085 __ LoadP(r5, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object | 1085 __ LoadP(r5, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
| 1086 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1086 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
| 1087 __ CompareObjectType(r5, r6, r6, LAST_JS_PROXY_TYPE); | 1087 __ CompareObjectType(r5, r6, r6, LAST_JS_PROXY_TYPE); |
| 1088 __ bgt(&non_proxy); | 1088 __ bgt(&non_proxy); |
| 1089 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy | 1089 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy |
| 1090 __ bind(&non_proxy); | 1090 __ bind(&non_proxy); |
| 1091 __ Push(r4, r3); // Smi and array | 1091 __ Push(r4, r3); // Smi and array |
| 1092 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset)); | 1092 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset)); |
| 1093 __ LoadSmiLiteral(r3, Smi::FromInt(0)); | 1093 __ LoadSmiLiteral(r3, Smi::FromInt(0)); |
| 1094 __ Push(r4, r3); // Fixed array length (as smi) and initial index. | 1094 __ Push(r4, r3); // Fixed array length (as smi) and initial index. |
| 1095 | 1095 |
| 1096 // Generate code for doing the condition check. | 1096 // Generate code for doing the condition check. |
| (...skipping 1999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3096 VisitForAccumulatorValue(args->at(0)); | 3096 VisitForAccumulatorValue(args->at(0)); |
| 3097 | 3097 |
| 3098 Label materialize_true, materialize_false; | 3098 Label materialize_true, materialize_false; |
| 3099 Label* if_true = NULL; | 3099 Label* if_true = NULL; |
| 3100 Label* if_false = NULL; | 3100 Label* if_false = NULL; |
| 3101 Label* fall_through = NULL; | 3101 Label* fall_through = NULL; |
| 3102 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, | 3102 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, |
| 3103 &if_false, &fall_through); | 3103 &if_false, &fall_through); |
| 3104 | 3104 |
| 3105 __ JumpIfSmi(r3, if_false); | 3105 __ JumpIfSmi(r3, if_false); |
| 3106 __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE); | 3106 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); |
| 3107 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 3107 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 3108 Split(ge, if_true, if_false, fall_through); | 3108 Split(ge, if_true, if_false, fall_through); |
| 3109 | 3109 |
| 3110 context()->Plug(if_true, if_false); | 3110 context()->Plug(if_true, if_false); |
| 3111 } | 3111 } |
| 3112 | 3112 |
| 3113 | 3113 |
| 3114 void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) { | 3114 void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) { |
| 3115 ZoneList<Expression*>* args = expr->arguments(); | 3115 ZoneList<Expression*>* args = expr->arguments(); |
| 3116 DCHECK(args->length() == 1); | 3116 DCHECK(args->length() == 1); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3385 VisitForAccumulatorValue(args->at(0)); | 3385 VisitForAccumulatorValue(args->at(0)); |
| 3386 | 3386 |
| 3387 // If the object is a smi, we return null. | 3387 // If the object is a smi, we return null. |
| 3388 __ JumpIfSmi(r3, &null); | 3388 __ JumpIfSmi(r3, &null); |
| 3389 | 3389 |
| 3390 // Check that the object is a JS object but take special care of JS | 3390 // Check that the object is a JS object but take special care of JS |
| 3391 // functions to make sure they have 'Function' as their class. | 3391 // functions to make sure they have 'Function' as their class. |
| 3392 // Assume that there are only two callable types, and one of them is at | 3392 // Assume that there are only two callable types, and one of them is at |
| 3393 // either end of the type range for JS object types. Saves extra comparisons. | 3393 // either end of the type range for JS object types. Saves extra comparisons. |
| 3394 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 3394 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
| 3395 __ CompareObjectType(r3, r3, r4, FIRST_SPEC_OBJECT_TYPE); | 3395 __ CompareObjectType(r3, r3, r4, FIRST_JS_RECEIVER_TYPE); |
| 3396 // Map is now in r3. | 3396 // Map is now in r3. |
| 3397 __ blt(&null); | 3397 __ blt(&null); |
| 3398 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 3398 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 3399 FIRST_SPEC_OBJECT_TYPE + 1); | 3399 FIRST_JS_RECEIVER_TYPE + 1); |
| 3400 __ beq(&function); | 3400 __ beq(&function); |
| 3401 | 3401 |
| 3402 __ cmpi(r4, Operand(LAST_SPEC_OBJECT_TYPE)); | 3402 __ cmpi(r4, Operand(LAST_JS_RECEIVER_TYPE)); |
| 3403 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_SPEC_OBJECT_TYPE - 1); | 3403 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_JS_RECEIVER_TYPE - 1); |
| 3404 __ beq(&function); | 3404 __ beq(&function); |
| 3405 // Assume that there is no larger type. | 3405 // Assume that there is no larger type. |
| 3406 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); | 3406 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); |
| 3407 | 3407 |
| 3408 // Check if the constructor in the map is a JS function. | 3408 // Check if the constructor in the map is a JS function. |
| 3409 Register instance_type = r5; | 3409 Register instance_type = r5; |
| 3410 __ GetMapConstructor(r3, r3, r4, instance_type); | 3410 __ GetMapConstructor(r3, r3, r4, instance_type); |
| 3411 __ cmpi(instance_type, Operand(JS_FUNCTION_TYPE)); | 3411 __ cmpi(instance_type, Operand(JS_FUNCTION_TYPE)); |
| 3412 __ bne(&non_function_constructor); | 3412 __ bne(&non_function_constructor); |
| 3413 | 3413 |
| (...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4650 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset)); | 4650 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset)); |
| 4651 __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset)); | 4651 __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset)); |
| 4652 __ andi(r4, r4, | 4652 __ andi(r4, r4, |
| 4653 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 4653 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 4654 __ cmpi(r4, Operand(1 << Map::kIsCallable)); | 4654 __ cmpi(r4, Operand(1 << Map::kIsCallable)); |
| 4655 Split(eq, if_true, if_false, fall_through); | 4655 Split(eq, if_true, if_false, fall_through); |
| 4656 } else if (String::Equals(check, factory->object_string())) { | 4656 } else if (String::Equals(check, factory->object_string())) { |
| 4657 __ JumpIfSmi(r3, if_false); | 4657 __ JumpIfSmi(r3, if_false); |
| 4658 __ CompareRoot(r3, Heap::kNullValueRootIndex); | 4658 __ CompareRoot(r3, Heap::kNullValueRootIndex); |
| 4659 __ beq(if_true); | 4659 __ beq(if_true); |
| 4660 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 4660 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 4661 __ CompareObjectType(r3, r3, r4, FIRST_SPEC_OBJECT_TYPE); | 4661 __ CompareObjectType(r3, r3, r4, FIRST_JS_RECEIVER_TYPE); |
| 4662 __ blt(if_false); | 4662 __ blt(if_false); |
| 4663 // Check for callable or undetectable objects => false. | 4663 // Check for callable or undetectable objects => false. |
| 4664 __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset)); | 4664 __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset)); |
| 4665 __ andi(r0, r4, | 4665 __ andi(r0, r4, |
| 4666 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 4666 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 4667 Split(eq, if_true, if_false, fall_through, cr0); | 4667 Split(eq, if_true, if_false, fall_through, cr0); |
| 4668 // clang-format off | 4668 // clang-format off |
| 4669 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 4669 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
| 4670 } else if (String::Equals(check, factory->type##_string())) { \ | 4670 } else if (String::Equals(check, factory->type##_string())) { \ |
| 4671 __ JumpIfSmi(r3, if_false); \ | 4671 __ JumpIfSmi(r3, if_false); \ |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4961 return ON_STACK_REPLACEMENT; | 4961 return ON_STACK_REPLACEMENT; |
| 4962 } | 4962 } |
| 4963 | 4963 |
| 4964 DCHECK(interrupt_address == | 4964 DCHECK(interrupt_address == |
| 4965 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4965 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4966 return OSR_AFTER_STACK_CHECK; | 4966 return OSR_AFTER_STACK_CHECK; |
| 4967 } | 4967 } |
| 4968 } // namespace internal | 4968 } // namespace internal |
| 4969 } // namespace v8 | 4969 } // namespace v8 |
| 4970 #endif // V8_TARGET_ARCH_PPC | 4970 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |