Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 __ ldr(dst, FieldMemOperand(src, offset)); | 164 __ ldr(dst, FieldMemOperand(src, offset)); |
| 165 } else { | 165 } else { |
| 166 // Calculate the offset into the properties array. | 166 // Calculate the offset into the properties array. |
| 167 int offset = index * kPointerSize + Array::kHeaderSize; | 167 int offset = index * kPointerSize + Array::kHeaderSize; |
| 168 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 168 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
| 169 __ ldr(dst, FieldMemOperand(dst, offset)); | 169 __ ldr(dst, FieldMemOperand(dst, offset)); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 | 173 |
| 174 void StubCompiler::GenerateLoadField(MacroAssembler* masm, | |
| 175 JSObject* object, | |
| 176 JSObject* holder, | |
| 177 Register receiver, | |
| 178 Register scratch1, | |
| 179 Register scratch2, | |
| 180 int index, | |
| 181 Label* miss_label) { | |
| 182 // Check that the receiver isn't a smi. | |
| 183 __ tst(receiver, Operand(kSmiTagMask)); | |
| 184 __ b(eq, miss_label); | |
| 185 | |
| 186 // Check that the maps haven't changed. | |
| 187 Register reg = | |
| 188 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 189 GenerateFastPropertyLoad(masm, r0, reg, holder, index); | |
| 190 __ Ret(); | |
| 191 } | |
| 192 | |
| 193 | |
| 194 void StubCompiler::GenerateLoadConstant(MacroAssembler* masm, | |
| 195 JSObject* object, | |
| 196 JSObject* holder, | |
| 197 Register receiver, | |
| 198 Register scratch1, | |
| 199 Register scratch2, | |
| 200 Object* value, | |
| 201 Label* miss_label) { | |
| 202 // Check that the receiver isn't a smi. | |
| 203 __ tst(receiver, Operand(kSmiTagMask)); | |
| 204 __ b(eq, miss_label); | |
| 205 | |
| 206 // Check that the maps haven't changed. | |
| 207 Register reg = | |
| 208 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 209 | |
| 210 // Return the constant value. | |
| 211 __ mov(r0, Operand(Handle<Object>(value))); | |
| 212 __ Ret(); | |
| 213 } | |
| 214 | |
| 215 | |
| 216 void StubCompiler::GenerateLoadCallback(MacroAssembler* masm, | |
| 217 JSObject* object, | |
| 218 JSObject* holder, | |
| 219 Register receiver, | |
| 220 Register name, | |
| 221 Register scratch1, | |
| 222 Register scratch2, | |
| 223 AccessorInfo* callback, | |
| 224 Label* miss_label) { | |
| 225 // Check that the receiver isn't a smi. | |
| 226 __ tst(receiver, Operand(kSmiTagMask)); | |
| 227 __ b(eq, miss_label); | |
| 228 | |
| 229 // Check that the maps haven't changed. | |
| 230 Register reg = | |
| 231 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 232 | |
| 233 // Push the arguments on the JS stack of the caller. | |
| 234 __ push(receiver); // receiver | |
| 235 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data | |
| 236 __ push(ip); | |
| 237 __ push(name); // name | |
| 238 __ push(reg); // holder | |
| 239 | |
| 240 // Do tail-call to the runtime system. | |
| 241 ExternalReference load_callback_property = | |
| 242 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | |
| 243 __ TailCallRuntime(load_callback_property, 4); | |
| 244 } | |
| 245 | |
| 246 | |
| 247 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, | |
| 248 JSObject* object, | |
| 249 JSObject* holder, | |
| 250 Smi* lookup_hint, | |
| 251 Register receiver, | |
| 252 Register name, | |
| 253 Register scratch1, | |
| 254 Register scratch2, | |
| 255 Label* miss_label) { | |
| 256 // Check that the receiver isn't a smi. | |
| 257 __ tst(receiver, Operand(kSmiTagMask)); | |
| 258 __ b(eq, miss_label); | |
| 259 | |
| 260 // Check that the maps haven't changed. | |
| 261 Register reg = | |
| 262 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
| 263 | |
| 264 // Push the arguments on the JS stack of the caller. | |
| 265 __ push(receiver); // receiver | |
| 266 __ push(reg); // holder | |
| 267 __ push(name); // name | |
| 268 __ mov(scratch1, Operand(lookup_hint)); | |
| 269 __ push(scratch1); | |
| 270 | |
| 271 // Do tail-call to the runtime system. | |
| 272 ExternalReference load_ic_property = | |
| 273 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | |
| 274 __ TailCallRuntime(load_ic_property, 4); | |
| 275 } | |
| 276 | |
| 277 | |
| 278 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 174 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
| 279 Register receiver, | 175 Register receiver, |
| 280 Register scratch, | 176 Register scratch, |
| 281 Label* miss_label) { | 177 Label* miss_label) { |
| 282 // Check that the receiver isn't a smi. | 178 // Check that the receiver isn't a smi. |
| 283 __ tst(receiver, Operand(kSmiTagMask)); | 179 __ tst(receiver, Operand(kSmiTagMask)); |
| 284 __ b(eq, miss_label); | 180 __ b(eq, miss_label); |
| 285 | 181 |
| 286 // Check that the object is a JS array. | 182 // Check that the object is a JS array. |
| 287 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); | 183 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 | 351 |
| 456 Handle<Code> ic(code); | 352 Handle<Code> ic(code); |
| 457 __ Jump(ic, RelocInfo::CODE_TARGET); | 353 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 458 } | 354 } |
| 459 | 355 |
| 460 | 356 |
| 461 #undef __ | 357 #undef __ |
| 462 #define __ ACCESS_MASM(masm()) | 358 #define __ ACCESS_MASM(masm()) |
| 463 | 359 |
| 464 | 360 |
| 361 Register StubCompiler::CheckPrototypes(JSObject* object, | |
|
antonm
2009/07/10 09:28:43
maybe it should go to macro-assembler?
| |
| 362 Register object_reg, | |
| 363 JSObject* holder, | |
| 364 Register holder_reg, | |
| 365 Register scratch, | |
| 366 String* name, | |
| 367 Label* miss) { | |
| 368 // Check that the maps haven't changed. | |
| 369 Register result = | |
| 370 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); | |
| 371 | |
| 372 // If we've skipped any global objects, it's not enough to verify | |
| 373 // that their maps haven't changed. | |
| 374 while (object != holder) { | |
| 375 if (object->IsGlobalObject()) { | |
|
antonm
2009/07/10 09:28:43
just curious, I guess there might be only single g
| |
| 376 GlobalObject* global = GlobalObject::cast(object); | |
| 377 Object* probe = global->EnsurePropertyCell(name); | |
| 378 if (probe->IsFailure()) { | |
| 379 set_failure(Failure::cast(probe)); | |
| 380 return result; | |
| 381 } | |
| 382 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | |
|
antonm
2009/07/10 09:28:43
for my education: why it must be the hole?
| |
| 383 ASSERT(cell->value()->IsTheHole()); | |
| 384 __ mov(scratch, Operand(Handle<Object>(cell))); | |
|
antonm
2009/07/10 09:28:43
cell always live not in new space, correct?
| |
| 385 __ ldr(scratch, | |
| 386 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 387 __ cmp(scratch, Operand(Factory::the_hole_value())); | |
| 388 __ b(ne, miss); | |
| 389 } | |
| 390 object = JSObject::cast(object->GetPrototype()); | |
|
antonm
2009/07/10 09:28:43
just for my education: it's always safe to assume
| |
| 391 } | |
| 392 | |
| 393 // Return the register containin the holder. | |
| 394 return result; | |
| 395 } | |
| 396 | |
| 397 | |
| 398 void StubCompiler::GenerateLoadField(JSObject* object, | |
|
antonm
2009/07/10 09:28:43
cosmetic issue: is the move of methods needed---if
| |
| 399 JSObject* holder, | |
| 400 Register receiver, | |
| 401 Register scratch1, | |
| 402 Register scratch2, | |
| 403 int index, | |
| 404 String* name, | |
| 405 Label* miss) { | |
| 406 // Check that the receiver isn't a smi. | |
| 407 __ tst(receiver, Operand(kSmiTagMask)); | |
| 408 __ b(eq, miss); | |
| 409 | |
| 410 // Check that the maps haven't changed. | |
| 411 Register reg = | |
| 412 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
| 413 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | |
| 414 __ Ret(); | |
| 415 } | |
| 416 | |
| 417 | |
| 418 void StubCompiler::GenerateLoadConstant(JSObject* object, | |
| 419 JSObject* holder, | |
| 420 Register receiver, | |
| 421 Register scratch1, | |
| 422 Register scratch2, | |
| 423 Object* value, | |
| 424 String* name, | |
| 425 Label* miss) { | |
| 426 // Check that the receiver isn't a smi. | |
| 427 __ tst(receiver, Operand(kSmiTagMask)); | |
| 428 __ b(eq, miss); | |
| 429 | |
| 430 // Check that the maps haven't changed. | |
| 431 Register reg = | |
| 432 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
| 433 | |
| 434 // Return the constant value. | |
| 435 __ mov(r0, Operand(Handle<Object>(value))); | |
| 436 __ Ret(); | |
| 437 } | |
| 438 | |
| 439 | |
| 440 void StubCompiler::GenerateLoadCallback(JSObject* object, | |
| 441 JSObject* holder, | |
| 442 Register receiver, | |
| 443 Register name_reg, | |
| 444 Register scratch1, | |
| 445 Register scratch2, | |
| 446 AccessorInfo* callback, | |
| 447 String* name, | |
| 448 Label* miss) { | |
| 449 // Check that the receiver isn't a smi. | |
| 450 __ tst(receiver, Operand(kSmiTagMask)); | |
| 451 __ b(eq, miss); | |
| 452 | |
| 453 // Check that the maps haven't changed. | |
| 454 Register reg = | |
| 455 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
| 456 | |
| 457 // Push the arguments on the JS stack of the caller. | |
| 458 __ push(receiver); // receiver | |
| 459 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data | |
| 460 __ push(ip); | |
| 461 __ push(name_reg); // name | |
| 462 __ push(reg); // holder | |
| 463 | |
| 464 // Do tail-call to the runtime system. | |
| 465 ExternalReference load_callback_property = | |
| 466 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | |
| 467 __ TailCallRuntime(load_callback_property, 4); | |
| 468 } | |
| 469 | |
| 470 | |
| 471 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | |
| 472 JSObject* holder, | |
| 473 Smi* lookup_hint, | |
| 474 Register receiver, | |
| 475 Register name_reg, | |
| 476 Register scratch1, | |
| 477 Register scratch2, | |
| 478 String* name, | |
| 479 Label* miss) { | |
| 480 // Check that the receiver isn't a smi. | |
| 481 __ tst(receiver, Operand(kSmiTagMask)); | |
| 482 __ b(eq, miss); | |
| 483 | |
| 484 // Check that the maps haven't changed. | |
| 485 Register reg = | |
| 486 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
| 487 | |
| 488 // Push the arguments on the JS stack of the caller. | |
| 489 __ push(receiver); // receiver | |
| 490 __ push(reg); // holder | |
| 491 __ push(name_reg); // name | |
| 492 __ mov(scratch1, Operand(lookup_hint)); | |
| 493 __ push(scratch1); | |
| 494 | |
| 495 // Do tail-call to the runtime system. | |
| 496 ExternalReference load_ic_property = | |
| 497 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | |
| 498 __ TailCallRuntime(load_ic_property, 4); | |
| 499 } | |
| 500 | |
| 501 | |
| 465 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { | 502 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { |
| 466 // ----------- S t a t e ------------- | 503 // ----------- S t a t e ------------- |
| 467 // -- r1: function | 504 // -- r1: function |
| 468 // -- lr: return address | 505 // -- lr: return address |
| 469 // ----------------------------------- | 506 // ----------------------------------- |
| 470 | 507 |
| 471 // Enter an internal frame. | 508 // Enter an internal frame. |
| 472 __ EnterInternalFrame(); | 509 __ EnterInternalFrame(); |
| 473 | 510 |
| 474 // Preserve the function. | 511 // Preserve the function. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 const int argc = arguments().immediate(); | 543 const int argc = arguments().immediate(); |
| 507 | 544 |
| 508 // Get the receiver of the function from the stack into r0. | 545 // Get the receiver of the function from the stack into r0. |
| 509 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 546 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 510 // Check that the receiver isn't a smi. | 547 // Check that the receiver isn't a smi. |
| 511 __ tst(r0, Operand(kSmiTagMask)); | 548 __ tst(r0, Operand(kSmiTagMask)); |
| 512 __ b(eq, &miss); | 549 __ b(eq, &miss); |
| 513 | 550 |
| 514 // Do the right check and compute the holder register. | 551 // Do the right check and compute the holder register. |
| 515 Register reg = | 552 Register reg = |
| 516 masm()->CheckMaps(JSObject::cast(object), r0, holder, r3, r2, &miss); | 553 CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss); |
| 517 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 554 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
| 518 | 555 |
| 519 // Check that the function really is a function. | 556 // Check that the function really is a function. |
| 520 __ tst(r1, Operand(kSmiTagMask)); | 557 __ tst(r1, Operand(kSmiTagMask)); |
| 521 __ b(eq, &miss); | 558 __ b(eq, &miss); |
| 522 // Get the map. | 559 // Get the map. |
| 523 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 560 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
| 524 __ b(ne, &miss); | 561 __ b(ne, &miss); |
| 525 | 562 |
| 526 // Patch the receiver on the stack with the global proxy if | 563 // Patch the receiver on the stack with the global proxy if |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 539 __ Jump(ic, RelocInfo::CODE_TARGET); | 576 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 540 | 577 |
| 541 // Return the generated code. | 578 // Return the generated code. |
| 542 return GetCode(FIELD, name); | 579 return GetCode(FIELD, name); |
| 543 } | 580 } |
| 544 | 581 |
| 545 | 582 |
| 546 Object* CallStubCompiler::CompileCallConstant(Object* object, | 583 Object* CallStubCompiler::CompileCallConstant(Object* object, |
| 547 JSObject* holder, | 584 JSObject* holder, |
| 548 JSFunction* function, | 585 JSFunction* function, |
| 586 String* name, | |
| 549 CheckType check) { | 587 CheckType check) { |
| 550 // ----------- S t a t e ------------- | 588 // ----------- S t a t e ------------- |
| 551 // -- lr: return address | 589 // -- lr: return address |
| 552 // ----------------------------------- | 590 // ----------------------------------- |
| 553 Label miss; | 591 Label miss; |
| 554 | 592 |
| 555 // Get the receiver from the stack | 593 // Get the receiver from the stack |
| 556 const int argc = arguments().immediate(); | 594 const int argc = arguments().immediate(); |
| 557 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 595 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 558 | 596 |
| 559 // Check that the receiver isn't a smi. | 597 // Check that the receiver isn't a smi. |
| 560 if (check != NUMBER_CHECK) { | 598 if (check != NUMBER_CHECK) { |
| 561 __ tst(r1, Operand(kSmiTagMask)); | 599 __ tst(r1, Operand(kSmiTagMask)); |
| 562 __ b(eq, &miss); | 600 __ b(eq, &miss); |
| 563 } | 601 } |
| 564 | 602 |
| 565 // Make sure that it's okay not to patch the on stack receiver | 603 // Make sure that it's okay not to patch the on stack receiver |
| 566 // unless we're doing a receiver map check. | 604 // unless we're doing a receiver map check. |
| 567 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 605 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 568 | 606 |
| 569 switch (check) { | 607 switch (check) { |
| 570 case RECEIVER_MAP_CHECK: | 608 case RECEIVER_MAP_CHECK: |
| 571 // Check that the maps haven't changed. | 609 // Check that the maps haven't changed. |
| 572 __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); | 610 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
| 573 | 611 |
| 574 // Patch the receiver on the stack with the global proxy if | 612 // Patch the receiver on the stack with the global proxy if |
| 575 // necessary. | 613 // necessary. |
| 576 if (object->IsGlobalObject()) { | 614 if (object->IsGlobalObject()) { |
| 577 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 615 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 578 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 616 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 579 } | 617 } |
| 580 break; | 618 break; |
| 581 | 619 |
| 582 case STRING_CHECK: | 620 case STRING_CHECK: |
| 583 // Check that the object is a two-byte string or a symbol. | 621 // Check that the object is a two-byte string or a symbol. |
| 584 __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); | 622 __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); |
| 585 __ b(hs, &miss); | 623 __ b(hs, &miss); |
| 586 // Check that the maps starting from the prototype haven't changed. | 624 // Check that the maps starting from the prototype haven't changed. |
| 587 GenerateLoadGlobalFunctionPrototype(masm(), | 625 GenerateLoadGlobalFunctionPrototype(masm(), |
| 588 Context::STRING_FUNCTION_INDEX, | 626 Context::STRING_FUNCTION_INDEX, |
| 589 r2); | 627 r2); |
| 590 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 628 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
| 591 r2, holder, r3, r1, &miss); | 629 r1, name, &miss); |
| 592 break; | 630 break; |
| 593 | 631 |
| 594 case NUMBER_CHECK: { | 632 case NUMBER_CHECK: { |
| 595 Label fast; | 633 Label fast; |
| 596 // Check that the object is a smi or a heap number. | 634 // Check that the object is a smi or a heap number. |
| 597 __ tst(r1, Operand(kSmiTagMask)); | 635 __ tst(r1, Operand(kSmiTagMask)); |
| 598 __ b(eq, &fast); | 636 __ b(eq, &fast); |
| 599 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); | 637 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); |
| 600 __ b(ne, &miss); | 638 __ b(ne, &miss); |
| 601 __ bind(&fast); | 639 __ bind(&fast); |
| 602 // Check that the maps starting from the prototype haven't changed. | 640 // Check that the maps starting from the prototype haven't changed. |
| 603 GenerateLoadGlobalFunctionPrototype(masm(), | 641 GenerateLoadGlobalFunctionPrototype(masm(), |
| 604 Context::NUMBER_FUNCTION_INDEX, | 642 Context::NUMBER_FUNCTION_INDEX, |
| 605 r2); | 643 r2); |
| 606 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 644 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
| 607 r2, holder, r3, r1, &miss); | 645 r1, name, &miss); |
| 608 break; | 646 break; |
| 609 } | 647 } |
| 610 | 648 |
| 611 case BOOLEAN_CHECK: { | 649 case BOOLEAN_CHECK: { |
| 612 Label fast; | 650 Label fast; |
| 613 // Check that the object is a boolean. | 651 // Check that the object is a boolean. |
| 614 __ cmp(r1, Operand(Factory::true_value())); | 652 __ cmp(r1, Operand(Factory::true_value())); |
| 615 __ b(eq, &fast); | 653 __ b(eq, &fast); |
| 616 __ cmp(r1, Operand(Factory::false_value())); | 654 __ cmp(r1, Operand(Factory::false_value())); |
| 617 __ b(ne, &miss); | 655 __ b(ne, &miss); |
| 618 __ bind(&fast); | 656 __ bind(&fast); |
| 619 // Check that the maps starting from the prototype haven't changed. | 657 // Check that the maps starting from the prototype haven't changed. |
| 620 GenerateLoadGlobalFunctionPrototype(masm(), | 658 GenerateLoadGlobalFunctionPrototype(masm(), |
| 621 Context::BOOLEAN_FUNCTION_INDEX, | 659 Context::BOOLEAN_FUNCTION_INDEX, |
| 622 r2); | 660 r2); |
| 623 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 661 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
| 624 r2, holder, r3, r1, &miss); | 662 r1, name, &miss); |
| 625 break; | 663 break; |
| 626 } | 664 } |
| 627 | 665 |
| 628 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: | 666 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: |
| 629 __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); | 667 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
| 630 // Make sure object->elements()->map() != Heap::hash_table_map() | 668 // Make sure object->elements()->map() != Heap::hash_table_map() |
| 631 // Get the elements array of the object. | 669 // Get the elements array of the object. |
| 632 __ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset)); | 670 __ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset)); |
| 633 // Check that the object is in fast mode (not dictionary). | 671 // Check that the object is in fast mode (not dictionary). |
| 634 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | 672 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); |
| 635 __ cmp(r2, Operand(Factory::hash_table_map())); | 673 __ cmp(r2, Operand(Factory::hash_table_map())); |
| 636 __ b(eq, &miss); | 674 __ b(eq, &miss); |
| 637 break; | 675 break; |
| 638 | 676 |
| 639 default: | 677 default: |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 | 743 |
| 706 // If the object is the holder then we know that it's a global | 744 // If the object is the holder then we know that it's a global |
| 707 // object which can only happen for contextual calls. In this case, | 745 // object which can only happen for contextual calls. In this case, |
| 708 // the receiver cannot be a smi. | 746 // the receiver cannot be a smi. |
| 709 if (object != holder) { | 747 if (object != holder) { |
| 710 __ tst(r0, Operand(kSmiTagMask)); | 748 __ tst(r0, Operand(kSmiTagMask)); |
| 711 __ b(eq, &miss); | 749 __ b(eq, &miss); |
| 712 } | 750 } |
| 713 | 751 |
| 714 // Check that the maps haven't changed. | 752 // Check that the maps haven't changed. |
| 715 masm()->CheckMaps(object, r0, holder, r3, r2, &miss); | 753 CheckPrototypes(object, r0, holder, r3, r2, name, &miss); |
| 716 | 754 |
| 717 // Get the value from the cell. | 755 // Get the value from the cell. |
| 718 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 756 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
| 719 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 757 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
| 720 | 758 |
| 721 // Check that the cell contains the same function. | 759 // Check that the cell contains the same function. |
| 722 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 760 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
| 723 __ b(ne, &miss); | 761 __ b(ne, &miss); |
| 724 | 762 |
| 725 // Patch the receiver on the stack with the global proxy if | 763 // Patch the receiver on the stack with the global proxy if |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 String* name) { | 972 String* name) { |
| 935 // ----------- S t a t e ------------- | 973 // ----------- S t a t e ------------- |
| 936 // -- r2 : name | 974 // -- r2 : name |
| 937 // -- lr : return address | 975 // -- lr : return address |
| 938 // -- [sp] : receiver | 976 // -- [sp] : receiver |
| 939 // ----------------------------------- | 977 // ----------------------------------- |
| 940 Label miss; | 978 Label miss; |
| 941 | 979 |
| 942 __ ldr(r0, MemOperand(sp, 0)); | 980 __ ldr(r0, MemOperand(sp, 0)); |
| 943 | 981 |
| 944 GenerateLoadField(masm(), object, holder, r0, r3, r1, index, &miss); | 982 GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); |
| 945 __ bind(&miss); | 983 __ bind(&miss); |
| 946 GenerateLoadMiss(masm(), Code::LOAD_IC); | 984 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 947 | 985 |
| 948 // Return the generated code. | 986 // Return the generated code. |
| 949 return GetCode(FIELD, name); | 987 return GetCode(FIELD, name); |
| 950 } | 988 } |
| 951 | 989 |
| 952 | 990 |
| 953 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, | 991 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, |
| 954 JSObject* holder, | 992 JSObject* holder, |
| 955 AccessorInfo* callback, | 993 AccessorInfo* callback, |
| 956 String* name) { | 994 String* name) { |
| 957 // ----------- S t a t e ------------- | 995 // ----------- S t a t e ------------- |
| 958 // -- r2 : name | 996 // -- r2 : name |
| 959 // -- lr : return address | 997 // -- lr : return address |
| 960 // -- [sp] : receiver | 998 // -- [sp] : receiver |
| 961 // ----------------------------------- | 999 // ----------------------------------- |
| 962 Label miss; | 1000 Label miss; |
| 963 | 1001 |
| 964 __ ldr(r0, MemOperand(sp, 0)); | 1002 __ ldr(r0, MemOperand(sp, 0)); |
| 965 GenerateLoadCallback(masm(), object, holder, r0, r2, r3, r1, callback, &miss); | 1003 GenerateLoadCallback(object, holder, r0, r2, r3, r1, callback, name, &miss); |
| 966 __ bind(&miss); | 1004 __ bind(&miss); |
| 967 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1005 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 968 | 1006 |
| 969 // Return the generated code. | 1007 // Return the generated code. |
| 970 return GetCode(CALLBACKS, name); | 1008 return GetCode(CALLBACKS, name); |
| 971 } | 1009 } |
| 972 | 1010 |
| 973 | 1011 |
| 974 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1012 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
| 975 JSObject* holder, | 1013 JSObject* holder, |
| 976 Object* value, | 1014 Object* value, |
| 977 String* name) { | 1015 String* name) { |
| 978 // ----------- S t a t e ------------- | 1016 // ----------- S t a t e ------------- |
| 979 // -- r2 : name | 1017 // -- r2 : name |
| 980 // -- lr : return address | 1018 // -- lr : return address |
| 981 // -- [sp] : receiver | 1019 // -- [sp] : receiver |
| 982 // ----------------------------------- | 1020 // ----------------------------------- |
| 983 Label miss; | 1021 Label miss; |
| 984 | 1022 |
| 985 __ ldr(r0, MemOperand(sp, 0)); | 1023 __ ldr(r0, MemOperand(sp, 0)); |
| 986 | 1024 |
| 987 GenerateLoadConstant(masm(), object, holder, r0, r3, r1, value, &miss); | 1025 GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); |
| 988 __ bind(&miss); | 1026 __ bind(&miss); |
| 989 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1027 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 990 | 1028 |
| 991 // Return the generated code. | 1029 // Return the generated code. |
| 992 return GetCode(CONSTANT_FUNCTION, name); | 1030 return GetCode(CONSTANT_FUNCTION, name); |
| 993 } | 1031 } |
| 994 | 1032 |
| 995 | 1033 |
| 996 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 1034 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, |
| 997 JSObject* holder, | 1035 JSObject* holder, |
| 998 String* name) { | 1036 String* name) { |
| 999 // ----------- S t a t e ------------- | 1037 // ----------- S t a t e ------------- |
| 1000 // -- r2 : name | 1038 // -- r2 : name |
| 1001 // -- lr : return address | 1039 // -- lr : return address |
| 1002 // -- [sp] : receiver | 1040 // -- [sp] : receiver |
| 1003 // ----------------------------------- | 1041 // ----------------------------------- |
| 1004 Label miss; | 1042 Label miss; |
| 1005 | 1043 |
| 1006 __ ldr(r0, MemOperand(sp, 0)); | 1044 __ ldr(r0, MemOperand(sp, 0)); |
| 1007 | 1045 |
| 1008 GenerateLoadInterceptor(masm(), | 1046 GenerateLoadInterceptor(object, |
| 1009 object, | |
| 1010 holder, | 1047 holder, |
| 1011 holder->InterceptorPropertyLookupHint(name), | 1048 holder->InterceptorPropertyLookupHint(name), |
| 1012 r0, | 1049 r0, |
| 1013 r2, | 1050 r2, |
| 1014 r3, | 1051 r3, |
| 1015 r1, | 1052 r1, |
| 1053 name, | |
| 1016 &miss); | 1054 &miss); |
| 1017 __ bind(&miss); | 1055 __ bind(&miss); |
| 1018 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1056 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1019 | 1057 |
| 1020 // Return the generated code. | 1058 // Return the generated code. |
| 1021 return GetCode(INTERCEPTOR, name); | 1059 return GetCode(INTERCEPTOR, name); |
| 1022 } | 1060 } |
| 1023 | 1061 |
| 1024 | 1062 |
| 1025 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 1063 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1041 | 1079 |
| 1042 // If the object is the holder then we know that it's a global | 1080 // If the object is the holder then we know that it's a global |
| 1043 // object which can only happen for contextual calls. In this case, | 1081 // object which can only happen for contextual calls. In this case, |
| 1044 // the receiver cannot be a smi. | 1082 // the receiver cannot be a smi. |
| 1045 if (object != holder) { | 1083 if (object != holder) { |
| 1046 __ tst(r1, Operand(kSmiTagMask)); | 1084 __ tst(r1, Operand(kSmiTagMask)); |
| 1047 __ b(eq, &miss); | 1085 __ b(eq, &miss); |
| 1048 } | 1086 } |
| 1049 | 1087 |
| 1050 // Check that the map of the global has not changed. | 1088 // Check that the map of the global has not changed. |
| 1051 masm()->CheckMaps(object, r1, holder, r3, r0, &miss); | 1089 CheckPrototypes(object, r1, holder, r3, r0, name, &miss); |
| 1052 | 1090 |
| 1053 // Get the value from the cell. | 1091 // Get the value from the cell. |
| 1054 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 1092 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
| 1055 __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 1093 __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
| 1056 | 1094 |
| 1057 // Check for deleted property if property can actually be deleted. | 1095 // Check for deleted property if property can actually be deleted. |
| 1058 if (!is_dont_delete) { | 1096 if (!is_dont_delete) { |
| 1059 __ cmp(r0, Operand(Factory::the_hole_value())); | 1097 __ cmp(r0, Operand(Factory::the_hole_value())); |
| 1060 __ b(eq, &miss); | 1098 __ b(eq, &miss); |
| 1061 } | 1099 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1084 // -- sp[4] : receiver | 1122 // -- sp[4] : receiver |
| 1085 // ----------------------------------- | 1123 // ----------------------------------- |
| 1086 Label miss; | 1124 Label miss; |
| 1087 | 1125 |
| 1088 __ ldr(r2, MemOperand(sp, 0)); | 1126 __ ldr(r2, MemOperand(sp, 0)); |
| 1089 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1127 __ ldr(r0, MemOperand(sp, kPointerSize)); |
| 1090 | 1128 |
| 1091 __ cmp(r2, Operand(Handle<String>(name))); | 1129 __ cmp(r2, Operand(Handle<String>(name))); |
| 1092 __ b(ne, &miss); | 1130 __ b(ne, &miss); |
| 1093 | 1131 |
| 1094 GenerateLoadField(masm(), receiver, holder, r0, r3, r1, index, &miss); | 1132 GenerateLoadField(receiver, holder, r0, r3, r1, index, name, &miss); |
| 1095 __ bind(&miss); | 1133 __ bind(&miss); |
| 1096 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1134 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1097 | 1135 |
| 1098 return GetCode(FIELD, name); | 1136 return GetCode(FIELD, name); |
| 1099 } | 1137 } |
| 1100 | 1138 |
| 1101 | 1139 |
| 1102 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 1140 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, |
| 1103 JSObject* receiver, | 1141 JSObject* receiver, |
| 1104 JSObject* holder, | 1142 JSObject* holder, |
| 1105 AccessorInfo* callback) { | 1143 AccessorInfo* callback) { |
| 1106 // ----------- S t a t e ------------- | 1144 // ----------- S t a t e ------------- |
| 1107 // -- lr : return address | 1145 // -- lr : return address |
| 1108 // -- sp[0] : key | 1146 // -- sp[0] : key |
| 1109 // -- sp[4] : receiver | 1147 // -- sp[4] : receiver |
| 1110 // ----------------------------------- | 1148 // ----------------------------------- |
| 1111 Label miss; | 1149 Label miss; |
| 1112 | 1150 |
| 1113 __ ldr(r2, MemOperand(sp, 0)); | 1151 __ ldr(r2, MemOperand(sp, 0)); |
| 1114 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1152 __ ldr(r0, MemOperand(sp, kPointerSize)); |
| 1115 | 1153 |
| 1116 __ cmp(r2, Operand(Handle<String>(name))); | 1154 __ cmp(r2, Operand(Handle<String>(name))); |
| 1117 __ b(ne, &miss); | 1155 __ b(ne, &miss); |
| 1118 | 1156 |
| 1119 GenerateLoadCallback(masm(), receiver, holder, r0, r2, r3, | 1157 GenerateLoadCallback(receiver, holder, r0, r2, r3, r1, callback, name, &miss); |
| 1120 r1, callback, &miss); | |
| 1121 __ bind(&miss); | 1158 __ bind(&miss); |
| 1122 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1159 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1123 | 1160 |
| 1124 return GetCode(CALLBACKS, name); | 1161 return GetCode(CALLBACKS, name); |
| 1125 } | 1162 } |
| 1126 | 1163 |
| 1127 | 1164 |
| 1128 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 1165 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
| 1129 JSObject* receiver, | 1166 JSObject* receiver, |
| 1130 JSObject* holder, | 1167 JSObject* holder, |
| 1131 Object* value) { | 1168 Object* value) { |
| 1132 // ----------- S t a t e ------------- | 1169 // ----------- S t a t e ------------- |
| 1133 // -- lr : return address | 1170 // -- lr : return address |
| 1134 // -- sp[0] : key | 1171 // -- sp[0] : key |
| 1135 // -- sp[4] : receiver | 1172 // -- sp[4] : receiver |
| 1136 // ----------------------------------- | 1173 // ----------------------------------- |
| 1137 Label miss; | 1174 Label miss; |
| 1138 | 1175 |
| 1139 // Check the key is the cached one | 1176 // Check the key is the cached one |
| 1140 __ ldr(r2, MemOperand(sp, 0)); | 1177 __ ldr(r2, MemOperand(sp, 0)); |
| 1141 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1178 __ ldr(r0, MemOperand(sp, kPointerSize)); |
| 1142 | 1179 |
| 1143 __ cmp(r2, Operand(Handle<String>(name))); | 1180 __ cmp(r2, Operand(Handle<String>(name))); |
| 1144 __ b(ne, &miss); | 1181 __ b(ne, &miss); |
| 1145 | 1182 |
| 1146 GenerateLoadConstant(masm(), receiver, holder, r0, r3, r1, value, &miss); | 1183 GenerateLoadConstant(receiver, holder, r0, r3, r1, value, name, &miss); |
| 1147 __ bind(&miss); | 1184 __ bind(&miss); |
| 1148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1185 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1149 | 1186 |
| 1150 // Return the generated code. | 1187 // Return the generated code. |
| 1151 return GetCode(CONSTANT_FUNCTION, name); | 1188 return GetCode(CONSTANT_FUNCTION, name); |
| 1152 } | 1189 } |
| 1153 | 1190 |
| 1154 | 1191 |
| 1155 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1192 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
| 1156 JSObject* holder, | 1193 JSObject* holder, |
| 1157 String* name) { | 1194 String* name) { |
| 1158 // ----------- S t a t e ------------- | 1195 // ----------- S t a t e ------------- |
| 1159 // -- lr : return address | 1196 // -- lr : return address |
| 1160 // -- sp[0] : key | 1197 // -- sp[0] : key |
| 1161 // -- sp[4] : receiver | 1198 // -- sp[4] : receiver |
| 1162 // ----------------------------------- | 1199 // ----------------------------------- |
| 1163 Label miss; | 1200 Label miss; |
| 1164 | 1201 |
| 1165 // Check the key is the cached one | 1202 // Check the key is the cached one |
| 1166 __ ldr(r2, MemOperand(sp, 0)); | 1203 __ ldr(r2, MemOperand(sp, 0)); |
| 1167 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1204 __ ldr(r0, MemOperand(sp, kPointerSize)); |
| 1168 | 1205 |
| 1169 __ cmp(r2, Operand(Handle<String>(name))); | 1206 __ cmp(r2, Operand(Handle<String>(name))); |
| 1170 __ b(ne, &miss); | 1207 __ b(ne, &miss); |
| 1171 | 1208 |
| 1172 GenerateLoadInterceptor(masm(), | 1209 GenerateLoadInterceptor(receiver, |
| 1173 receiver, | |
| 1174 holder, | 1210 holder, |
| 1175 Smi::FromInt(JSObject::kLookupInHolder), | 1211 Smi::FromInt(JSObject::kLookupInHolder), |
| 1176 r0, | 1212 r0, |
| 1177 r2, | 1213 r2, |
| 1178 r3, | 1214 r3, |
| 1179 r1, | 1215 r1, |
| 1216 name, | |
| 1180 &miss); | 1217 &miss); |
| 1181 __ bind(&miss); | 1218 __ bind(&miss); |
| 1182 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1219 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1183 | 1220 |
| 1184 return GetCode(INTERCEPTOR, name); | 1221 return GetCode(INTERCEPTOR, name); |
| 1185 } | 1222 } |
| 1186 | 1223 |
| 1187 | 1224 |
| 1188 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 1225 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
| 1189 // ----------- S t a t e ------------- | 1226 // ----------- S t a t e ------------- |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1282 __ Jump(ic, RelocInfo::CODE_TARGET); | 1319 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 1283 | 1320 |
| 1284 // Return the generated code. | 1321 // Return the generated code. |
| 1285 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1322 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 1286 } | 1323 } |
| 1287 | 1324 |
| 1288 | 1325 |
| 1289 #undef __ | 1326 #undef __ |
| 1290 | 1327 |
| 1291 } } // namespace v8::internal | 1328 } } // namespace v8::internal |
| OLD | NEW |