Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2360 // (9) Sliced string. Replace subject with parent. Go to (4). | 2360 // (9) Sliced string. Replace subject with parent. Go to (4). |
| 2361 // Load offset into r9 and replace subject string with parent. | 2361 // Load offset into r9 and replace subject string with parent. |
| 2362 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2362 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2363 __ SmiUntag(r9); | 2363 __ SmiUntag(r9); |
| 2364 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2364 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2365 __ jmp(&check_underlying); // Go to (4). | 2365 __ jmp(&check_underlying); // Go to (4). |
| 2366 #endif // V8_INTERPRETED_REGEXP | 2366 #endif // V8_INTERPRETED_REGEXP |
| 2367 } | 2367 } |
| 2368 | 2368 |
| 2369 | 2369 |
| 2370 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | |
| 2371 // r0 : number of arguments to the construct function | |
| 2372 // r2 : Feedback vector | |
| 2373 // r3 : slot in feedback vector (Smi) | |
| 2374 // r1 : the function to call | |
| 2375 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
| 2376 | |
| 2377 // Arguments register must be smi-tagged to call out. | |
|
Erik Corry
2015/04/02 12:54:11
Comment clarification propopsal:
Arguments registe
| |
| 2378 __ SmiTag(r0); | |
| 2379 __ Push(r3, r2, r1, r0); | |
| 2380 | |
| 2381 __ CallStub(stub); | |
| 2382 | |
| 2383 __ Pop(r3, r2, r1, r0); | |
| 2384 __ SmiUntag(r0); | |
| 2385 } | |
| 2386 | |
| 2387 | |
| 2370 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2388 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 2371 // Cache the called function in a feedback vector slot. Cache states | 2389 // Cache the called function in a feedback vector slot. Cache states |
| 2372 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2390 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2373 // megamorphic. | 2391 // megamorphic. |
| 2374 // r0 : number of arguments to the construct function | 2392 // r0 : number of arguments to the construct function |
| 2375 // r1 : the function to call | 2393 // r1 : the function to call |
| 2376 // r2 : Feedback vector | 2394 // r2 : Feedback vector |
| 2377 // r3 : slot in feedback vector (Smi) | 2395 // r3 : slot in feedback vector (Smi) |
| 2378 Label initialize, done, miss, megamorphic, not_array_function; | 2396 Label initialize, done, miss, megamorphic, not_array_function; |
| 2379 | 2397 |
| 2380 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2398 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2381 masm->isolate()->heap()->megamorphic_symbol()); | 2399 masm->isolate()->heap()->megamorphic_symbol()); |
| 2382 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2400 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2383 masm->isolate()->heap()->uninitialized_symbol()); | 2401 masm->isolate()->heap()->uninitialized_symbol()); |
| 2384 | 2402 |
| 2385 // Load the cache state into r4. | 2403 // Load the cache state into r4. |
| 2386 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2404 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2387 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 2405 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
| 2388 | 2406 |
| 2389 // A monomorphic cache hit or an already megamorphic state: invoke the | 2407 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 2390 // function without changing the state. | 2408 // function without changing the state. |
| 2391 __ cmp(r4, r1); | 2409 Label check_allocation_site; |
| 2410 Register feedback_map = r5; | |
| 2411 Register weak_value = r8; | |
| 2412 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); | |
| 2413 __ cmp(r1, weak_value); | |
| 2392 __ b(eq, &done); | 2414 __ b(eq, &done); |
| 2415 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); | |
|
Erik Corry
2015/04/02 12:54:11
We just treated r4 as a weak cell (3 lines up), no
mvstanton
2015/04/02 14:00:38
Correct, but it's not random. It's a performance o
| |
| 2416 __ b(eq, &done); | |
| 2417 __ ldr(feedback_map, FieldMemOperand(r4, 0)); | |
|
Erik Corry
2015/04/02 12:54:11
HeapObject::kMapOffset would be better than 0
| |
| 2418 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | |
| 2419 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); | |
| 2420 | |
| 2421 // If r1 is not equal to the weak cell value, and the weak cell value is | |
|
Erik Corry
2015/04/02 12:54:11
Comment clarification suggestion:
r1 -> function
| |
| 2422 // cleared, we have a new chance to become monomorphic. | |
| 2423 __ JumpIfSmi(weak_value, &initialize); | |
| 2424 __ jmp(&megamorphic); | |
| 2393 | 2425 |
| 2394 if (!FLAG_pretenuring_call_new) { | 2426 if (!FLAG_pretenuring_call_new) { |
| 2427 __ bind(&check_allocation_site); | |
| 2395 // If we came here, we need to see if we are the array function. | 2428 // If we came here, we need to see if we are the array function. |
| 2396 // If we didn't have a matching function, and we didn't find the megamorph | 2429 // If we didn't have a matching function, and we didn't find the megamorph |
| 2397 // sentinel, then we have in the slot either some other function or an | 2430 // sentinel, then we have in the slot either some other function or an |
| 2398 // AllocationSite. Do a map check on the object in ecx. | 2431 // AllocationSite. Do a map check on the object in ecx. |
|
Erik Corry
2015/04/02 12:54:11
ecx? :-)
| |
| 2399 __ ldr(r5, FieldMemOperand(r4, 0)); | 2432 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); |
| 2400 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | |
| 2401 __ b(ne, &miss); | 2433 __ b(ne, &miss); |
| 2402 | 2434 |
| 2403 // Make sure the function is the Array() function | 2435 // Make sure the function is the Array() function |
| 2404 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2436 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
| 2405 __ cmp(r1, r4); | 2437 __ cmp(r1, r4); |
| 2406 __ b(ne, &megamorphic); | 2438 __ b(ne, &megamorphic); |
| 2407 __ jmp(&done); | 2439 __ jmp(&done); |
| 2408 } | 2440 } |
| 2409 | 2441 |
| 2410 __ bind(&miss); | 2442 __ bind(&miss); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2426 | 2458 |
| 2427 if (!FLAG_pretenuring_call_new) { | 2459 if (!FLAG_pretenuring_call_new) { |
| 2428 // Make sure the function is the Array() function | 2460 // Make sure the function is the Array() function |
| 2429 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2461 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
| 2430 __ cmp(r1, r4); | 2462 __ cmp(r1, r4); |
| 2431 __ b(ne, ¬_array_function); | 2463 __ b(ne, ¬_array_function); |
| 2432 | 2464 |
| 2433 // The target function is the Array constructor, | 2465 // The target function is the Array constructor, |
| 2434 // Create an AllocationSite if we don't already have it, store it in the | 2466 // Create an AllocationSite if we don't already have it, store it in the |
| 2435 // slot. | 2467 // slot. |
| 2436 { | 2468 CreateAllocationSiteStub create_stub(masm->isolate()); |
| 2437 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2469 CallStubInRecordCallTarget(masm, &create_stub); |
| 2438 | |
| 2439 // Arguments register must be smi-tagged to call out. | |
| 2440 __ SmiTag(r0); | |
| 2441 __ Push(r3, r2, r1, r0); | |
| 2442 | |
| 2443 CreateAllocationSiteStub create_stub(masm->isolate()); | |
| 2444 __ CallStub(&create_stub); | |
| 2445 | |
| 2446 __ Pop(r3, r2, r1, r0); | |
| 2447 __ SmiUntag(r0); | |
| 2448 } | |
| 2449 __ b(&done); | 2470 __ b(&done); |
| 2450 | 2471 |
| 2451 __ bind(¬_array_function); | 2472 __ bind(¬_array_function); |
| 2452 } | 2473 } |
| 2453 | 2474 |
| 2454 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2475 CreateWeakCellStub create_stub(masm->isolate()); |
| 2455 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 2476 CallStubInRecordCallTarget(masm, &create_stub); |
| 2456 __ str(r1, MemOperand(r4, 0)); | |
| 2457 | |
| 2458 __ Push(r4, r2, r1); | |
| 2459 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, | |
| 2460 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
| 2461 __ Pop(r4, r2, r1); | |
| 2462 | |
| 2463 __ bind(&done); | 2477 __ bind(&done); |
| 2464 } | 2478 } |
| 2465 | 2479 |
| 2466 | 2480 |
| 2467 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2481 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2468 // Do not transform the receiver for strict mode functions. | 2482 // Do not transform the receiver for strict mode functions. |
| 2469 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2483 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 2470 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); | 2484 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); |
| 2471 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + | 2485 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + |
| 2472 kSmiTagSize))); | 2486 kSmiTagSize))); |
| (...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5284 kStackUnwindSpace, NULL, | 5298 kStackUnwindSpace, NULL, |
| 5285 MemOperand(fp, 6 * kPointerSize), NULL); | 5299 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5286 } | 5300 } |
| 5287 | 5301 |
| 5288 | 5302 |
| 5289 #undef __ | 5303 #undef __ |
| 5290 | 5304 |
| 5291 } } // namespace v8::internal | 5305 } } // namespace v8::internal |
| 5292 | 5306 |
| 5293 #endif // V8_TARGET_ARCH_ARM | 5307 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |