Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 247373002: CallICStub with a "never patch" approach until customization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ports. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3178 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 3189
3190 __ Push(function); 3190 __ Push(function);
3191 __ RecordWrite(feedback_vector, scratch1, function, kLRHasNotBeenSaved, 3191 __ RecordWrite(feedback_vector, scratch1, function, kLRHasNotBeenSaved,
3192 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 3192 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3193 __ Pop(function); 3193 __ Pop(function);
3194 3194
3195 __ Bind(&done); 3195 __ Bind(&done);
3196 } 3196 }
3197 3197
3198 3198
3199 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
3200 // Do not transform the receiver for strict mode functions.
3201 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
3202 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset));
3203 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont);
3204
3205 // Do not transform the receiver for native (Compilerhints already in x3).
3206 __ Tbnz(w4, SharedFunctionInfo::kNative, cont);
3207 }
3208
3209
3210 static void EmitSlowCase(MacroAssembler* masm,
3211 int argc,
3212 Register function,
3213 Register type,
3214 Label* non_function) {
3215 // Check for function proxy.
3216 // x10 : function type.
3217 __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, non_function);
3218 __ Push(function); // put proxy as additional argument
3219 __ Mov(x0, argc + 1);
3220 __ Mov(x2, 0);
3221 __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
3222 {
3223 Handle<Code> adaptor =
3224 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
3225 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3226 }
3227
3228 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3229 // of the original receiver from the call site).
3230 __ Bind(non_function);
3231 __ Poke(function, argc * kXRegSize);
3232 __ Mov(x0, argc); // Set up the number of arguments.
3233 __ Mov(x2, 0);
3234 __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
3235 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3236 RelocInfo::CODE_TARGET);
3237 }
3238
3239
3240 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
3241 // Wrap the receiver and patch it back onto the stack.
3242 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
3243 __ Push(x1, x3);
3244 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3245 __ Pop(x1);
3246 }
3247 __ Poke(x0, argc * kPointerSize);
3248 __ B(cont);
3249 }
3250
3251
3199 void CallFunctionStub::Generate(MacroAssembler* masm) { 3252 void CallFunctionStub::Generate(MacroAssembler* masm) {
3200 ASM_LOCATION("CallFunctionStub::Generate"); 3253 ASM_LOCATION("CallFunctionStub::Generate");
3201 // x1 function the function to call 3254 // x1 function the function to call
3202 // x2 : feedback vector 3255
3203 // x3 : slot in feedback vector (smi) (if x2 is not the megamorphic symbol)
3204 Register function = x1; 3256 Register function = x1;
3205 Register cache_cell = x2;
3206 Register slot = x3;
3207 Register type = x4; 3257 Register type = x4;
3208 Label slow, non_function, wrap, cont; 3258 Label slow, non_function, wrap, cont;
3209 3259
3210 // TODO(jbramley): This function has a lot of unnamed registers. Name them, 3260 // TODO(jbramley): This function has a lot of unnamed registers. Name them,
3211 // and tidy things up a bit. 3261 // and tidy things up a bit.
3212 3262
3213 if (NeedsChecks()) { 3263 if (NeedsChecks()) {
3214 // Check that the function is really a JavaScript function. 3264 // Check that the function is really a JavaScript function.
3215 __ JumpIfSmi(function, &non_function); 3265 __ JumpIfSmi(function, &non_function);
3216 3266
3217 // Goto slow case if we do not have a function. 3267 // Goto slow case if we do not have a function.
3218 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); 3268 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
3219
3220 if (RecordCallTarget()) {
3221 GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5);
3222 // Type information was updated. Because we may call Array, which
3223 // expects either undefined or an AllocationSite in ebx we need
3224 // to set ebx to undefined.
3225 __ LoadRoot(cache_cell, Heap::kUndefinedValueRootIndex);
3226 }
3227 } 3269 }
3228 3270
3229 // Fast-case: Invoke the function now. 3271 // Fast-case: Invoke the function now.
3230 // x1 function pushed function 3272 // x1 function pushed function
3231 ParameterCount actual(argc_); 3273 int argc = argc_;
3274 ParameterCount actual(argc);
3232 3275
3233 if (CallAsMethod()) { 3276 if (CallAsMethod()) {
3234 if (NeedsChecks()) { 3277 if (NeedsChecks()) {
3235 // Do not transform the receiver for strict mode functions. 3278 EmitContinueIfStrictOrNative(masm, &cont);
3236 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
3237 __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset));
3238 __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, &cont);
3239
3240 // Do not transform the receiver for native (Compilerhints already in x3).
3241 __ Tbnz(w4, SharedFunctionInfo::kNative, &cont);
3242 } 3279 }
3243 3280
3244 // Compute the receiver in sloppy mode. 3281 // Compute the receiver in sloppy mode.
3245 __ Peek(x3, argc_ * kPointerSize); 3282 __ Peek(x3, argc * kPointerSize);
3246 3283
3247 if (NeedsChecks()) { 3284 if (NeedsChecks()) {
3248 __ JumpIfSmi(x3, &wrap); 3285 __ JumpIfSmi(x3, &wrap);
3249 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); 3286 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
3250 } else { 3287 } else {
3251 __ B(&wrap); 3288 __ B(&wrap);
3252 } 3289 }
3253 3290
3254 __ Bind(&cont); 3291 __ Bind(&cont);
3255 } 3292 }
3293
3256 __ InvokeFunction(function, 3294 __ InvokeFunction(function,
3257 actual, 3295 actual,
3258 JUMP_FUNCTION, 3296 JUMP_FUNCTION,
3259 NullCallWrapper()); 3297 NullCallWrapper());
3260 3298
3261 if (NeedsChecks()) { 3299 if (NeedsChecks()) {
3262 // Slow-case: Non-function called. 3300 // Slow-case: Non-function called.
3263 __ Bind(&slow); 3301 __ Bind(&slow);
3264 if (RecordCallTarget()) { 3302 EmitSlowCase(masm, argc, function, type, &non_function);
3265 // If there is a call target cache, mark it megamorphic in the
3266 // non-function case. MegamorphicSentinel is an immortal immovable object
3267 // (megamorphic symbol) so no write barrier is needed.
3268 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
3269 masm->isolate()->heap()->megamorphic_symbol());
3270 __ Add(x12, cache_cell, Operand::UntagSmiAndScale(slot,
3271 kPointerSizeLog2));
3272 __ LoadRoot(x11, Heap::kMegamorphicSymbolRootIndex);
3273 __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize));
3274 }
3275 // Check for function proxy.
3276 // x10 : function type.
3277 __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, &non_function);
3278 __ Push(function); // put proxy as additional argument
3279 __ Mov(x0, argc_ + 1);
3280 __ Mov(x2, 0);
3281 __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
3282 {
3283 Handle<Code> adaptor =
3284 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
3285 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3286 }
3287
3288 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3289 // of the original receiver from the call site).
3290 __ Bind(&non_function);
3291 __ Poke(function, argc_ * kXRegSize);
3292 __ Mov(x0, argc_); // Set up the number of arguments.
3293 __ Mov(x2, 0);
3294 __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
3295 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3296 RelocInfo::CODE_TARGET);
3297 } 3303 }
3298 3304
3299 if (CallAsMethod()) { 3305 if (CallAsMethod()) {
3300 __ Bind(&wrap); 3306 __ Bind(&wrap);
3301 // Wrap the receiver and patch it back onto the stack. 3307 EmitWrapCase(masm, argc, &cont);
3302 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
3303 __ Push(x1, x3);
3304 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3305 __ Pop(x1);
3306 }
3307 __ Poke(x0, argc_ * kPointerSize);
3308 __ B(&cont);
3309 } 3308 }
3310 } 3309 }
3311 3310
3312 3311
3313 void CallConstructStub::Generate(MacroAssembler* masm) { 3312 void CallConstructStub::Generate(MacroAssembler* masm) {
3314 ASM_LOCATION("CallConstructStub::Generate"); 3313 ASM_LOCATION("CallConstructStub::Generate");
3315 // x0 : number of arguments 3314 // x0 : number of arguments
3316 // x1 : the function to call 3315 // x1 : the function to call
3317 // x2 : feedback vector 3316 // x2 : feedback vector
3318 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol) 3317 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3373 __ GetBuiltinFunction(x1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3372 __ GetBuiltinFunction(x1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3374 3373
3375 __ Bind(&do_call); 3374 __ Bind(&do_call);
3376 // Set expected number of arguments to zero (not changing x0). 3375 // Set expected number of arguments to zero (not changing x0).
3377 __ Mov(x2, 0); 3376 __ Mov(x2, 0);
3378 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3377 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
3379 RelocInfo::CODE_TARGET); 3378 RelocInfo::CODE_TARGET);
3380 } 3379 }
3381 3380
3382 3381
3382 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
3383 __ Ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3384 __ Ldr(vector, FieldMemOperand(vector,
3385 JSFunction::kSharedFunctionInfoOffset));
3386 __ Ldr(vector, FieldMemOperand(vector,
3387 SharedFunctionInfo::kFeedbackVectorOffset));
3388 }
3389
3390
3391 void CallICStub::Generate(MacroAssembler* masm) {
3392 ASM_LOCATION("CallICStub");
3393
3394 // x1 - function
3395 // x3 - slot id (Smi)
3396 Label extra_checks_or_miss, slow_start;
3397 Label slow, non_function, wrap, cont;
3398 Label have_js_function;
3399 int argc = state_.arg_count();
3400 ParameterCount actual(argc);
3401
3402 Register function = x1;
3403 Register feedback_vector = x2;
3404 Register index = x3;
3405 Register type = x4;
3406
3407 EmitLoadTypeFeedbackVector(masm, feedback_vector);
3408
3409 // The checks. First, does x1 match the recorded monomorphic target?
3410 __ Add(x4, feedback_vector,
3411 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
3412 __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize));
3413
3414 __ Cmp(x4, function);
3415 __ B(ne, &extra_checks_or_miss);
3416
3417 __ bind(&have_js_function);
3418 if (state_.CallAsMethod()) {
3419 EmitContinueIfStrictOrNative(masm, &cont);
3420
3421 // Compute the receiver in sloppy mode.
3422 __ Peek(x3, argc * kPointerSize);
3423
3424 __ JumpIfSmi(x3, &wrap);
3425 __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
3426
3427 __ Bind(&cont);
3428 }
3429
3430 __ InvokeFunction(function,
3431 actual,
3432 JUMP_FUNCTION,
3433 NullCallWrapper());
3434
3435 __ bind(&slow);
3436 EmitSlowCase(masm, argc, function, type, &non_function);
3437
3438 if (state_.CallAsMethod()) {
3439 __ bind(&wrap);
3440 EmitWrapCase(masm, argc, &cont);
3441 }
3442
3443 __ bind(&extra_checks_or_miss);
3444 Label miss;
3445
3446 __ JumpIfRoot(x4, Heap::kMegamorphicSymbolRootIndex, &slow_start);
3447 __ JumpIfRoot(x4, Heap::kUninitializedSymbolRootIndex, &miss);
3448
3449 if (!FLAG_trace_ic) {
3450 // We are going megamorphic, and we don't want to visit the runtime.
3451 __ Add(x4, feedback_vector,
3452 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
3453 __ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex);
3454 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
3455 __ B(&slow_start);
3456 }
3457
3458 // We are here because tracing is on or we are going monomorphic.
3459 __ bind(&miss);
3460 GenerateMiss(masm);
3461
3462 // the slow case
3463 __ bind(&slow_start);
3464
3465 // Check that the function is really a JavaScript function.
3466 __ JumpIfSmi(function, &non_function);
3467
3468 // Goto slow case if we do not have a function.
3469 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
3470 __ B(&have_js_function);
3471 }
3472
3473
3474 void CallICStub::GenerateMiss(MacroAssembler* masm) {
3475 ASM_LOCATION("CallICStub[Miss]");
3476
3477 // Get the receiver of the function from the stack; 1 ~ return address.
3478 __ Peek(x4, (state_.arg_count() + 1) * kPointerSize);
3479
3480 {
3481 FrameScope scope(masm, StackFrame::INTERNAL);
3482
3483 // Push the receiver and the function and feedback info.
3484 __ Push(x4, x1, x2, x3);
3485
3486 // Call the entry.
3487 ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
3488 masm->isolate());
3489 __ CallExternalReference(miss, 4);
3490
3491 // Move result to edi and exit the internal frame.
3492 __ Mov(x1, x0);
3493 }
3494 }
3495
3496
3383 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3497 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3384 // If the receiver is a smi trigger the non-string case. 3498 // If the receiver is a smi trigger the non-string case.
3385 __ JumpIfSmi(object_, receiver_not_string_); 3499 __ JumpIfSmi(object_, receiver_not_string_);
3386 3500
3387 // Fetch the instance type of the receiver into result register. 3501 // Fetch the instance type of the receiver into result register.
3388 __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 3502 __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
3389 __ Ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 3503 __ Ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
3390 3504
3391 // If the receiver is not a string trigger the non-string case. 3505 // If the receiver is not a string trigger the non-string case.
3392 __ TestAndBranchIfAnySet(result_, kIsNotStringMask, receiver_not_string_); 3506 __ TestAndBranchIfAnySet(result_, kIsNotStringMask, receiver_not_string_);
(...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after
5427 MemOperand(fp, 6 * kPointerSize), 5541 MemOperand(fp, 6 * kPointerSize),
5428 NULL); 5542 NULL);
5429 } 5543 }
5430 5544
5431 5545
5432 #undef __ 5546 #undef __
5433 5547
5434 } } // namespace v8::internal 5548 } } // namespace v8::internal
5435 5549
5436 #endif // V8_TARGET_ARCH_ARM64 5550 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698