| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 descriptor->register_param_count_ = 4; | 103 descriptor->register_param_count_ = 4; |
| 104 descriptor->register_params_ = registers; | 104 descriptor->register_params_ = registers; |
| 105 descriptor->deoptimization_handler_ = | 105 descriptor->deoptimization_handler_ = |
| 106 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; | 106 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 110 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
| 111 Isolate* isolate, | 111 Isolate* isolate, |
| 112 CodeStubInterfaceDescriptor* descriptor) { | 112 CodeStubInterfaceDescriptor* descriptor) { |
| 113 static Register registers[] = { ebx }; | 113 static Register registers[] = { ebx, edx }; |
| 114 descriptor->register_param_count_ = 1; | 114 descriptor->register_param_count_ = 2; |
| 115 descriptor->register_params_ = registers; | 115 descriptor->register_params_ = registers; |
| 116 descriptor->deoptimization_handler_ = NULL; | 116 descriptor->deoptimization_handler_ = NULL; |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( | 120 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( |
| 121 Isolate* isolate, | 121 Isolate* isolate, |
| 122 CodeStubInterfaceDescriptor* descriptor) { | 122 CodeStubInterfaceDescriptor* descriptor) { |
| 123 static Register registers[] = { edx, ecx }; | 123 static Register registers[] = { edx, ecx }; |
| 124 descriptor->register_param_count_ = 2; | 124 descriptor->register_param_count_ = 2; |
| (...skipping 2207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2332 __ bind(&miss); | 2332 __ bind(&miss); |
| 2333 GenerateMiss(masm); | 2333 GenerateMiss(masm); |
| 2334 } | 2334 } |
| 2335 | 2335 |
| 2336 | 2336 |
| 2337 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2337 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 2338 // Cache the called function in a global property cell. Cache states | 2338 // Cache the called function in a global property cell. Cache states |
| 2339 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2339 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2340 // megamorphic. | 2340 // megamorphic. |
| 2341 // eax : number of arguments to the construct function | 2341 // eax : number of arguments to the construct function |
| 2342 // ebx : cache cell for call target | 2342 // ebx : Feedback vector |
| 2343 // edx : slot in feedback vector (Smi) |
| 2343 // edi : the function to call | 2344 // edi : the function to call |
| 2344 Isolate* isolate = masm->isolate(); | 2345 Isolate* isolate = masm->isolate(); |
| 2345 Label initialize, done, miss, megamorphic, not_array_function; | 2346 Label initialize, done, miss, megamorphic, not_array_function; |
| 2346 | 2347 |
| 2347 // Load the cache state into ecx. | 2348 // Load the cache state into ecx. |
| 2348 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); | 2349 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 2350 FixedArray::kHeaderSize)); |
| 2349 | 2351 |
| 2350 // A monomorphic cache hit or an already megamorphic state: invoke the | 2352 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 2351 // function without changing the state. | 2353 // function without changing the state. |
| 2352 __ cmp(ecx, edi); | 2354 __ cmp(ecx, edi); |
| 2353 __ j(equal, &done); | 2355 __ j(equal, &done, Label::kFar); |
| 2354 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 2356 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
| 2355 __ j(equal, &done); | 2357 __ j(equal, &done, Label::kFar); |
| 2356 | 2358 |
| 2357 // If we came here, we need to see if we are the array function. | 2359 // If we came here, we need to see if we are the array function. |
| 2358 // If we didn't have a matching function, and we didn't find the megamorph | 2360 // If we didn't have a matching function, and we didn't find the megamorph |
| 2359 // sentinel, then we have in the cell either some other function or an | 2361 // sentinel, then we have in the cell either some other function or an |
| 2360 // AllocationSite. Do a map check on the object in ecx. | 2362 // AllocationSite. Do a map check on the object in ecx. |
| 2361 Handle<Map> allocation_site_map = | 2363 Handle<Map> allocation_site_map = |
| 2362 masm->isolate()->factory()->allocation_site_map(); | 2364 masm->isolate()->factory()->allocation_site_map(); |
| 2363 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 2365 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
| 2364 __ j(not_equal, &miss); | 2366 __ j(not_equal, &miss); |
| 2365 | 2367 |
| 2366 // Load the global or builtins object from the current context | 2368 // Load the global or builtins object from the current context |
| 2367 __ LoadGlobalContext(ecx); | 2369 __ LoadGlobalContext(ecx); |
| 2368 // Make sure the function is the Array() function | 2370 // Make sure the function is the Array() function |
| 2369 __ cmp(edi, Operand(ecx, | 2371 __ cmp(edi, Operand(ecx, |
| 2370 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 2372 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
| 2371 __ j(not_equal, &megamorphic); | 2373 __ j(not_equal, &megamorphic); |
| 2372 __ jmp(&done); | 2374 __ jmp(&done, Label::kFar); |
| 2373 | 2375 |
| 2374 __ bind(&miss); | 2376 __ bind(&miss); |
| 2375 | 2377 |
| 2376 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2378 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 2377 // megamorphic. | 2379 // megamorphic. |
| 2378 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate))); | 2380 __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate))); |
| 2379 __ j(equal, &initialize); | 2381 __ j(equal, &initialize); |
| 2380 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2382 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 2381 // write-barrier is needed. | 2383 // write-barrier is needed. |
| 2382 __ bind(&megamorphic); | 2384 __ bind(&megamorphic); |
| 2383 __ mov(FieldOperand(ebx, Cell::kValueOffset), | 2385 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
| 2384 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 2386 FixedArray::kHeaderSize), |
| 2385 __ jmp(&done, Label::kNear); | 2387 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
| 2388 __ jmp(&done, Label::kFar); |
| 2386 | 2389 |
| 2387 // An uninitialized cache is patched with the function or sentinel to | 2390 // An uninitialized cache is patched with the function or sentinel to |
| 2388 // indicate the ElementsKind if function is the Array constructor. | 2391 // indicate the ElementsKind if function is the Array constructor. |
| 2389 __ bind(&initialize); | 2392 __ bind(&initialize); |
| 2390 __ LoadGlobalContext(ecx); | 2393 __ LoadGlobalContext(ecx); |
| 2391 // Make sure the function is the Array() function | 2394 // Make sure the function is the Array() function |
| 2392 __ cmp(edi, Operand(ecx, | 2395 __ cmp(edi, Operand(ecx, |
| 2393 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 2396 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
| 2394 __ j(not_equal, ¬_array_function); | 2397 __ j(not_equal, ¬_array_function); |
| 2395 | 2398 |
| 2396 // The target function is the Array constructor, | 2399 // The target function is the Array constructor, |
| 2397 // Create an AllocationSite if we don't already have it, store it in the cell | 2400 // Create an AllocationSite if we don't already have it, store it in the cell |
| 2398 { | 2401 { |
| 2399 FrameScope scope(masm, StackFrame::INTERNAL); | 2402 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2400 | 2403 |
| 2401 // Arguments register must be smi-tagged to call out. | 2404 // Arguments register must be smi-tagged to call out. |
| 2402 __ SmiTag(eax); | 2405 __ SmiTag(eax); |
| 2403 __ push(eax); | 2406 __ push(eax); |
| 2404 __ push(edi); | 2407 __ push(edi); |
| 2408 __ push(edx); |
| 2405 __ push(ebx); | 2409 __ push(ebx); |
| 2406 | 2410 |
| 2407 CreateAllocationSiteStub create_stub; | 2411 CreateAllocationSiteStub create_stub; |
| 2408 __ CallStub(&create_stub); | 2412 __ CallStub(&create_stub); |
| 2409 | 2413 |
| 2410 __ pop(ebx); | 2414 __ pop(ebx); |
| 2415 __ pop(edx); |
| 2411 __ pop(edi); | 2416 __ pop(edi); |
| 2412 __ pop(eax); | 2417 __ pop(eax); |
| 2413 __ SmiUntag(eax); | 2418 __ SmiUntag(eax); |
| 2414 } | 2419 } |
| 2415 __ jmp(&done); | 2420 __ jmp(&done); |
| 2416 | 2421 |
| 2417 __ bind(¬_array_function); | 2422 __ bind(¬_array_function); |
| 2418 __ mov(FieldOperand(ebx, Cell::kValueOffset), edi); | 2423 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
| 2419 // No need for a write barrier here - cells are rescanned. | 2424 FixedArray::kHeaderSize), |
| 2425 edi); |
| 2426 // We won't need edx or ebx anymore, just save edi |
| 2427 __ push(edi); |
| 2428 __ push(ebx); |
| 2429 __ push(edx); |
| 2430 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, |
| 2431 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 2432 __ pop(edx); |
| 2433 __ pop(ebx); |
| 2434 __ pop(edi); |
| 2420 | 2435 |
| 2421 __ bind(&done); | 2436 __ bind(&done); |
| 2422 } | 2437 } |
| 2423 | 2438 |
| 2424 | 2439 |
| 2425 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2440 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 2426 // ebx : cache cell for call target | 2441 // ebx : feedback vector |
| 2442 // edx : (only if ebx is not undefined) slot in feedback vector (Smi) |
| 2427 // edi : the function to call | 2443 // edi : the function to call |
| 2428 Isolate* isolate = masm->isolate(); | 2444 Isolate* isolate = masm->isolate(); |
| 2429 Label slow, non_function; | 2445 Label slow, non_function; |
| 2430 | 2446 |
| 2431 // Check that the function really is a JavaScript function. | 2447 // Check that the function really is a JavaScript function. |
| 2432 __ JumpIfSmi(edi, &non_function); | 2448 __ JumpIfSmi(edi, &non_function); |
| 2433 | 2449 |
| 2434 // Goto slow case if we do not have a function. | 2450 // Goto slow case if we do not have a function. |
| 2435 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2451 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2436 __ j(not_equal, &slow); | 2452 __ j(not_equal, &slow); |
| 2437 | 2453 |
| 2438 if (RecordCallTarget()) { | 2454 if (RecordCallTarget()) { |
| 2439 GenerateRecordCallTarget(masm); | 2455 GenerateRecordCallTarget(masm); |
| 2440 } | 2456 } |
| 2441 | 2457 |
| 2442 // Fast-case: Just invoke the function. | 2458 // Fast-case: Just invoke the function. |
| 2443 ParameterCount actual(argc_); | 2459 ParameterCount actual(argc_); |
| 2444 | 2460 |
| 2445 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2461 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2446 | 2462 |
| 2447 // Slow-case: Non-function called. | 2463 // Slow-case: Non-function called. |
| 2448 __ bind(&slow); | 2464 __ bind(&slow); |
| 2449 if (RecordCallTarget()) { | 2465 if (RecordCallTarget()) { |
| 2450 // If there is a call target cache, mark it megamorphic in the | 2466 // If there is a call target cache, mark it megamorphic in the |
| 2451 // non-function case. MegamorphicSentinel is an immortal immovable | 2467 // non-function case. MegamorphicSentinel is an immortal immovable |
| 2452 // object (undefined) so no write barrier is needed. | 2468 // object (undefined) so no write barrier is needed. |
| 2453 __ mov(FieldOperand(ebx, Cell::kValueOffset), | 2469 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
| 2454 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 2470 FixedArray::kHeaderSize), |
| 2471 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
| 2455 } | 2472 } |
| 2456 // Check for function proxy. | 2473 // Check for function proxy. |
| 2457 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | 2474 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); |
| 2458 __ j(not_equal, &non_function); | 2475 __ j(not_equal, &non_function); |
| 2459 __ pop(ecx); | 2476 __ pop(ecx); |
| 2460 __ push(edi); // put proxy as additional argument under return address | 2477 __ push(edi); // put proxy as additional argument under return address |
| 2461 __ push(ecx); | 2478 __ push(ecx); |
| 2462 __ Set(eax, Immediate(argc_ + 1)); | 2479 __ Set(eax, Immediate(argc_ + 1)); |
| 2463 __ Set(ebx, Immediate(0)); | 2480 __ Set(ebx, Immediate(0)); |
| 2464 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 2481 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); |
| 2465 { | 2482 { |
| 2466 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 2483 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); |
| 2467 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 2484 __ jmp(adaptor, RelocInfo::CODE_TARGET); |
| 2468 } | 2485 } |
| 2469 | 2486 |
| 2470 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 2487 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 2471 // of the original receiver from the call site). | 2488 // of the original receiver from the call site). |
| 2472 __ bind(&non_function); | 2489 __ bind(&non_function); |
| 2473 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); | 2490 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); |
| 2474 __ Set(eax, Immediate(argc_)); | 2491 __ Set(eax, Immediate(argc_)); |
| 2475 __ Set(ebx, Immediate(0)); | 2492 __ Set(ebx, Immediate(0)); |
| 2476 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 2493 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 2477 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | 2494 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); |
| 2478 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 2495 __ jmp(adaptor, RelocInfo::CODE_TARGET); |
| 2479 } | 2496 } |
| 2480 | 2497 |
| 2481 | 2498 |
| 2482 void CallConstructStub::Generate(MacroAssembler* masm) { | 2499 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2483 // eax : number of arguments | 2500 // eax : number of arguments |
| 2484 // ebx : cache cell for call target | 2501 // ebx : feedback vector |
| 2502 // edx : (only if ebx is not undefined) slot in feedback vector (Smi) |
| 2485 // edi : constructor function | 2503 // edi : constructor function |
| 2486 Label slow, non_function_call; | 2504 Label slow, non_function_call; |
| 2487 | 2505 |
| 2488 // Check that function is not a smi. | 2506 // Check that function is not a smi. |
| 2489 __ JumpIfSmi(edi, &non_function_call); | 2507 __ JumpIfSmi(edi, &non_function_call); |
| 2490 // Check that function is a JSFunction. | 2508 // Check that function is a JSFunction. |
| 2491 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2509 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2492 __ j(not_equal, &slow); | 2510 __ j(not_equal, &slow); |
| 2493 | 2511 |
| 2494 if (RecordCallTarget()) { | 2512 if (RecordCallTarget()) { |
| (...skipping 2619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5114 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 5132 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 5115 } else { | 5133 } else { |
| 5116 UNREACHABLE(); | 5134 UNREACHABLE(); |
| 5117 } | 5135 } |
| 5118 } | 5136 } |
| 5119 | 5137 |
| 5120 | 5138 |
| 5121 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5139 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 5122 // ----------- S t a t e ------------- | 5140 // ----------- S t a t e ------------- |
| 5123 // -- eax : argc (only if argument_count_ == ANY) | 5141 // -- eax : argc (only if argument_count_ == ANY) |
| 5124 // -- ebx : type info cell | 5142 // -- ebx : feedback vector (fixed array or undefined) |
| 5143 // -- edx : slot index (if ebx is fixed array) |
| 5125 // -- edi : constructor | 5144 // -- edi : constructor |
| 5126 // -- esp[0] : return address | 5145 // -- esp[0] : return address |
| 5127 // -- esp[4] : last argument | 5146 // -- esp[4] : last argument |
| 5128 // ----------------------------------- | 5147 // ----------------------------------- |
| 5129 Handle<Object> undefined_sentinel( | 5148 Handle<Object> undefined_sentinel( |
| 5130 masm->isolate()->heap()->undefined_value(), | 5149 masm->isolate()->heap()->undefined_value(), |
| 5131 masm->isolate()); | 5150 masm->isolate()); |
| 5132 | 5151 |
| 5133 if (FLAG_debug_code) { | 5152 if (FLAG_debug_code) { |
| 5134 // The array construct code is only set for the global and natives | 5153 // The array construct code is only set for the global and natives |
| 5135 // builtin Array functions which always have maps. | 5154 // builtin Array functions which always have maps. |
| 5136 | 5155 |
| 5137 // Initial map for the builtin Array function should be a map. | 5156 // Initial map for the builtin Array function should be a map. |
| 5138 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 5157 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 5139 // Will both indicate a NULL and a Smi. | 5158 // Will both indicate a NULL and a Smi. |
| 5140 __ test(ecx, Immediate(kSmiTagMask)); | 5159 __ test(ecx, Immediate(kSmiTagMask)); |
| 5141 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 5160 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
| 5142 __ CmpObjectType(ecx, MAP_TYPE, ecx); | 5161 __ CmpObjectType(ecx, MAP_TYPE, ecx); |
| 5143 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 5162 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
| 5144 | 5163 |
| 5145 // We should either have undefined in ebx or a valid cell | 5164 // We should either have undefined in ebx or a valid cell |
| 5146 Label okay_here; | 5165 Label okay_here; |
| 5147 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 5166 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); |
| 5148 __ cmp(ebx, Immediate(undefined_sentinel)); | 5167 __ cmp(ebx, Immediate(undefined_sentinel)); |
| 5149 __ j(equal, &okay_here); | 5168 __ j(equal, &okay_here); |
| 5150 __ cmp(FieldOperand(ebx, 0), Immediate(cell_map)); | 5169 __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map)); |
| 5151 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); | 5170 __ Assert(equal, kExpectedFixedArrayInRegisterEbx); |
| 5171 |
| 5172 // edx should be a smi if we don't have undefined in ebx. |
| 5173 __ AssertSmi(edx); |
| 5174 |
| 5152 __ bind(&okay_here); | 5175 __ bind(&okay_here); |
| 5153 } | 5176 } |
| 5154 | 5177 |
| 5155 Label no_info; | 5178 Label no_info; |
| 5156 // If the type cell is undefined, or contains anything other than an | 5179 // If the type cell is undefined, or contains anything other than an |
| 5157 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5180 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
| 5158 __ cmp(ebx, Immediate(undefined_sentinel)); | 5181 __ cmp(ebx, Immediate(undefined_sentinel)); |
| 5159 __ j(equal, &no_info); | 5182 __ j(equal, &no_info); |
| 5160 __ mov(ebx, FieldOperand(ebx, Cell::kValueOffset)); | 5183 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 5184 FixedArray::kHeaderSize)); |
| 5161 __ cmp(FieldOperand(ebx, 0), Immediate( | 5185 __ cmp(FieldOperand(ebx, 0), Immediate( |
| 5162 masm->isolate()->factory()->allocation_site_map())); | 5186 masm->isolate()->factory()->allocation_site_map())); |
| 5163 __ j(not_equal, &no_info); | 5187 __ j(not_equal, &no_info); |
| 5164 | 5188 |
| 5165 // Only look at the lower 16 bits of the transition info. | 5189 // Only look at the lower 16 bits of the transition info. |
| 5166 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); | 5190 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); |
| 5167 __ SmiUntag(edx); | 5191 __ SmiUntag(edx); |
| 5168 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 5192 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
| 5169 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); | 5193 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); |
| 5170 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 5194 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5414 Operand(ebp, 7 * kPointerSize), | 5438 Operand(ebp, 7 * kPointerSize), |
| 5415 NULL); | 5439 NULL); |
| 5416 } | 5440 } |
| 5417 | 5441 |
| 5418 | 5442 |
| 5419 #undef __ | 5443 #undef __ |
| 5420 | 5444 |
| 5421 } } // namespace v8::internal | 5445 } } // namespace v8::internal |
| 5422 | 5446 |
| 5423 #endif // V8_TARGET_ARCH_IA32 | 5447 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |