| 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/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 287 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
| 288 __ bind(&done); | 288 __ bind(&done); |
| 289 | 289 |
| 290 SetVar(new_target_var, r3, r5, r6); | 290 SetVar(new_target_var, r3, r5, r6); |
| 291 } | 291 } |
| 292 | 292 |
| 293 Variable* arguments = scope()->arguments(); | 293 Variable* arguments = scope()->arguments(); |
| 294 if (arguments != NULL) { | 294 if (arguments != NULL) { |
| 295 // Function uses arguments object. | 295 // Function uses arguments object. |
| 296 Comment cmnt(masm_, "[ Allocate arguments object"); | 296 Comment cmnt(masm_, "[ Allocate arguments object"); |
| 297 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); |
| 297 if (!function_in_register_r4) { | 298 if (!function_in_register_r4) { |
| 298 // Load this again, if it's used by the local context below. | 299 // Load this again, if it's used by the local context below. |
| 299 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 300 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 300 } else { | |
| 301 __ mr(r6, r4); | |
| 302 } | 301 } |
| 303 // Receiver is just before the parameters on the caller's stack. | 302 // Receiver is just before the parameters on the caller's stack. |
| 304 int num_parameters = info->scope()->num_parameters(); | 303 int num_parameters = info->scope()->num_parameters(); |
| 305 int offset = num_parameters * kPointerSize; | 304 int offset = num_parameters * kPointerSize; |
| 306 __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 305 __ LoadSmiLiteral(ArgumentsAccessNewDescriptor::parameter_count(), |
| 307 __ LoadSmiLiteral(r4, Smi::FromInt(num_parameters)); | 306 Smi::FromInt(num_parameters)); |
| 308 __ Push(r6, r5, r4); | 307 __ addi(ArgumentsAccessNewDescriptor::parameter_pointer(), fp, |
| 308 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
| 309 | 309 |
| 310 // Arguments to ArgumentsAccessStub: | 310 // Arguments to ArgumentsAccessStub: |
| 311 // function, receiver address, parameter count. | 311 // function, parameter pointer, parameter count. |
| 312 // The stub will rewrite receiver and parameter count if the previous | 312 // The stub will rewrite parameter pointer and parameter count if the |
| 313 // stack frame was an arguments adapter frame. | 313 // previous stack frame was an arguments adapter frame. |
| 314 ArgumentsAccessStub::Type type; | 314 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); |
| 315 if (is_strict(language_mode()) || !has_simple_parameters()) { | 315 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( |
| 316 type = ArgumentsAccessStub::NEW_STRICT; | 316 is_unmapped, literal()->has_duplicate_parameters()); |
| 317 } else if (literal()->has_duplicate_parameters()) { | |
| 318 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | |
| 319 } else { | |
| 320 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | |
| 321 } | |
| 322 ArgumentsAccessStub stub(isolate(), type); | 317 ArgumentsAccessStub stub(isolate(), type); |
| 323 __ CallStub(&stub); | 318 __ CallStub(&stub); |
| 324 | 319 |
| 325 SetVar(arguments, r3, r4, r5); | 320 SetVar(arguments, r3, r4, r5); |
| 326 } | 321 } |
| 327 | 322 |
| 328 if (FLAG_trace) { | 323 if (FLAG_trace) { |
| 329 __ CallRuntime(Runtime::kTraceEnter, 0); | 324 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 330 } | 325 } |
| 331 | 326 |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 __ b(&loop); | 1083 __ b(&loop); |
| 1089 | 1084 |
| 1090 __ bind(&no_descriptors); | 1085 __ bind(&no_descriptors); |
| 1091 __ Drop(1); | 1086 __ Drop(1); |
| 1092 __ b(&exit); | 1087 __ b(&exit); |
| 1093 | 1088 |
| 1094 // We got a fixed array in register r3. Iterate through that. | 1089 // We got a fixed array in register r3. Iterate through that. |
| 1095 Label non_proxy; | 1090 Label non_proxy; |
| 1096 __ bind(&fixed_array); | 1091 __ bind(&fixed_array); |
| 1097 | 1092 |
| 1098 __ Move(r4, FeedbackVector()); | 1093 __ EmitLoadTypeFeedbackVector(r4); |
| 1099 __ mov(r5, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 1094 __ mov(r5, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
| 1100 int vector_index = FeedbackVector()->GetIndex(slot); | 1095 int vector_index = SmiFromSlot(slot)->value(); |
| 1101 __ StoreP( | 1096 __ StoreP( |
| 1102 r5, FieldMemOperand(r4, FixedArray::OffsetOfElementAt(vector_index)), r0); | 1097 r5, FieldMemOperand(r4, FixedArray::OffsetOfElementAt(vector_index)), r0); |
| 1103 | 1098 |
| 1104 __ LoadSmiLiteral(r4, Smi::FromInt(1)); // Smi indicates slow check | 1099 __ LoadSmiLiteral(r4, Smi::FromInt(1)); // Smi indicates slow check |
| 1105 __ LoadP(r5, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object | 1100 __ LoadP(r5, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
| 1106 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1101 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 1107 __ CompareObjectType(r5, r6, r6, LAST_JS_PROXY_TYPE); | 1102 __ CompareObjectType(r5, r6, r6, LAST_JS_PROXY_TYPE); |
| 1108 __ bgt(&non_proxy); | 1103 __ bgt(&non_proxy); |
| 1109 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy | 1104 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy |
| 1110 __ bind(&non_proxy); | 1105 __ bind(&non_proxy); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 Label materialized; | 1457 Label materialized; |
| 1463 // Registers will be used as follows: | 1458 // Registers will be used as follows: |
| 1464 // r8 = materialized value (RegExp literal) | 1459 // r8 = materialized value (RegExp literal) |
| 1465 // r7 = JS function, literals array | 1460 // r7 = JS function, literals array |
| 1466 // r6 = literal index | 1461 // r6 = literal index |
| 1467 // r5 = RegExp pattern | 1462 // r5 = RegExp pattern |
| 1468 // r4 = RegExp flags | 1463 // r4 = RegExp flags |
| 1469 // r3 = RegExp literal clone | 1464 // r3 = RegExp literal clone |
| 1470 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1465 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1471 __ LoadP(r7, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1466 __ LoadP(r7, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 1472 int literal_offset = | 1467 int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index()); |
| 1473 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | |
| 1474 __ LoadP(r8, FieldMemOperand(r7, literal_offset), r0); | 1468 __ LoadP(r8, FieldMemOperand(r7, literal_offset), r0); |
| 1475 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1469 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 1476 __ cmp(r8, ip); | 1470 __ cmp(r8, ip); |
| 1477 __ bne(&materialized); | 1471 __ bne(&materialized); |
| 1478 | 1472 |
| 1479 // Create regexp literal using runtime function. | 1473 // Create regexp literal using runtime function. |
| 1480 // Result will be in r3. | 1474 // Result will be in r3. |
| 1481 __ LoadSmiLiteral(r6, Smi::FromInt(expr->literal_index())); | 1475 __ LoadSmiLiteral(r6, Smi::FromInt(expr->literal_index())); |
| 1482 __ mov(r5, Operand(expr->pattern())); | 1476 __ mov(r5, Operand(expr->pattern())); |
| 1483 __ mov(r4, Operand(expr->flags())); | 1477 __ mov(r4, Operand(expr->flags())); |
| (...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 | 3169 |
| 3176 // Call the construct call builtin that handles allocation and | 3170 // Call the construct call builtin that handles allocation and |
| 3177 // constructor invocation. | 3171 // constructor invocation. |
| 3178 SetConstructCallPosition(expr); | 3172 SetConstructCallPosition(expr); |
| 3179 | 3173 |
| 3180 // Load function and argument count into r4 and r3. | 3174 // Load function and argument count into r4 and r3. |
| 3181 __ mov(r3, Operand(arg_count)); | 3175 __ mov(r3, Operand(arg_count)); |
| 3182 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); | 3176 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); |
| 3183 | 3177 |
| 3184 // Record call targets in unoptimized code. | 3178 // Record call targets in unoptimized code. |
| 3185 __ Move(r5, FeedbackVector()); | 3179 __ EmitLoadTypeFeedbackVector(r5); |
| 3186 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); | 3180 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); |
| 3187 | 3181 |
| 3188 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); | 3182 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); |
| 3189 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3183 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3190 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 3184 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 3191 // Restore context register. | 3185 // Restore context register. |
| 3192 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3186 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3193 context()->Plug(r3); | 3187 context()->Plug(r3); |
| 3194 } | 3188 } |
| 3195 | 3189 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3215 | 3209 |
| 3216 // Load original constructor into r7. | 3210 // Load original constructor into r7. |
| 3217 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 3211 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
| 3218 __ mr(r7, result_register()); | 3212 __ mr(r7, result_register()); |
| 3219 | 3213 |
| 3220 // Load function and argument count into r1 and r0. | 3214 // Load function and argument count into r1 and r0. |
| 3221 __ mov(r3, Operand(arg_count)); | 3215 __ mov(r3, Operand(arg_count)); |
| 3222 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); | 3216 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); |
| 3223 | 3217 |
| 3224 // Record call targets in unoptimized code. | 3218 // Record call targets in unoptimized code. |
| 3225 __ Move(r5, FeedbackVector()); | 3219 __ EmitLoadTypeFeedbackVector(r5); |
| 3226 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); | 3220 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); |
| 3227 | 3221 |
| 3228 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3222 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3229 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3223 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3230 | 3224 |
| 3231 RecordJSReturnSite(expr); | 3225 RecordJSReturnSite(expr); |
| 3232 | 3226 |
| 3233 // Restore context register. | 3227 // Restore context register. |
| 3234 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3228 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3235 context()->Plug(r3); | 3229 context()->Plug(r3); |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3828 | 3822 |
| 3829 // Load the argument into r3 and convert it. | 3823 // Load the argument into r3 and convert it. |
| 3830 VisitForAccumulatorValue(args->at(0)); | 3824 VisitForAccumulatorValue(args->at(0)); |
| 3831 | 3825 |
| 3832 Label convert, done_convert; | 3826 Label convert, done_convert; |
| 3833 __ JumpIfSmi(r3, &convert); | 3827 __ JumpIfSmi(r3, &convert); |
| 3834 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); | 3828 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); |
| 3835 __ CompareObjectType(r3, r4, r4, LAST_NAME_TYPE); | 3829 __ CompareObjectType(r3, r4, r4, LAST_NAME_TYPE); |
| 3836 __ ble(&done_convert); | 3830 __ ble(&done_convert); |
| 3837 __ bind(&convert); | 3831 __ bind(&convert); |
| 3838 ToStringStub stub(isolate()); | 3832 __ Push(r3); |
| 3839 __ CallStub(&stub); | 3833 __ CallRuntime(Runtime::kToName, 1); |
| 3840 __ bind(&done_convert); | 3834 __ bind(&done_convert); |
| 3841 context()->Plug(r3); | 3835 context()->Plug(r3); |
| 3842 } | 3836 } |
| 3843 | 3837 |
| 3844 | 3838 |
| 3845 void FullCodeGenerator::EmitToObject(CallRuntime* expr) { | 3839 void FullCodeGenerator::EmitToObject(CallRuntime* expr) { |
| 3846 ZoneList<Expression*>* args = expr->arguments(); | 3840 ZoneList<Expression*>* args = expr->arguments(); |
| 3847 DCHECK_EQ(1, args->length()); | 3841 DCHECK_EQ(1, args->length()); |
| 3848 // Load the argument into r3 and convert it. | 3842 // Load the argument into r3 and convert it. |
| 3849 VisitForAccumulatorValue(args->at(0)); | 3843 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5223 return ON_STACK_REPLACEMENT; | 5217 return ON_STACK_REPLACEMENT; |
| 5224 } | 5218 } |
| 5225 | 5219 |
| 5226 DCHECK(interrupt_address == | 5220 DCHECK(interrupt_address == |
| 5227 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5221 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5228 return OSR_AFTER_STACK_CHECK; | 5222 return OSR_AFTER_STACK_CHECK; |
| 5229 } | 5223 } |
| 5230 } // namespace internal | 5224 } // namespace internal |
| 5231 } // namespace v8 | 5225 } // namespace v8 |
| 5232 #endif // V8_TARGET_ARCH_PPC | 5226 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |