| 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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   535 } |   535 } | 
|   536  |   536  | 
|   537  |   537  | 
|   538 void MacroAssembler::PopTryHandler() { |   538 void MacroAssembler::PopTryHandler() { | 
|   539   ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |   539   ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 
|   540   pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address))); |   540   pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address))); | 
|   541   add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |   541   add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 
|   542 } |   542 } | 
|   543  |   543  | 
|   544  |   544  | 
|   545 Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg, |  | 
|   546                                    JSObject* holder, Register holder_reg, |  | 
|   547                                    Register scratch, |  | 
|   548                                    int save_at_depth, |  | 
|   549                                    Label* miss) { |  | 
|   550   // Make sure there's no overlap between scratch and the other |  | 
|   551   // registers. |  | 
|   552   ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg)); |  | 
|   553  |  | 
|   554   // Keep track of the current object in register reg. |  | 
|   555   Register reg = object_reg; |  | 
|   556   int depth = 0; |  | 
|   557  |  | 
|   558   if (save_at_depth == depth) { |  | 
|   559     mov(Operand(esp, kPointerSize), object_reg); |  | 
|   560   } |  | 
|   561  |  | 
|   562   // Check the maps in the prototype chain. |  | 
|   563   // Traverse the prototype chain from the object and do map checks. |  | 
|   564   while (object != holder) { |  | 
|   565     depth++; |  | 
|   566  |  | 
|   567     // Only global objects and objects that do not require access |  | 
|   568     // checks are allowed in stubs. |  | 
|   569     ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |  | 
|   570  |  | 
|   571     JSObject* prototype = JSObject::cast(object->GetPrototype()); |  | 
|   572     if (Heap::InNewSpace(prototype)) { |  | 
|   573       // Get the map of the current object. |  | 
|   574       mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |  | 
|   575       cmp(Operand(scratch), Immediate(Handle<Map>(object->map()))); |  | 
|   576       // Branch on the result of the map check. |  | 
|   577       j(not_equal, miss, not_taken); |  | 
|   578       // Check access rights to the global object.  This has to happen |  | 
|   579       // after the map check so that we know that the object is |  | 
|   580       // actually a global object. |  | 
|   581       if (object->IsJSGlobalProxy()) { |  | 
|   582         CheckAccessGlobalProxy(reg, scratch, miss); |  | 
|   583  |  | 
|   584         // Restore scratch register to be the map of the object. |  | 
|   585         // We load the prototype from the map in the scratch register. |  | 
|   586         mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |  | 
|   587       } |  | 
|   588       // The prototype is in new space; we cannot store a reference |  | 
|   589       // to it in the code. Load it from the map. |  | 
|   590       reg = holder_reg;  // from now the object is in holder_reg |  | 
|   591       mov(reg, FieldOperand(scratch, Map::kPrototypeOffset)); |  | 
|   592     } else { |  | 
|   593       // Check the map of the current object. |  | 
|   594       cmp(FieldOperand(reg, HeapObject::kMapOffset), |  | 
|   595           Immediate(Handle<Map>(object->map()))); |  | 
|   596       // Branch on the result of the map check. |  | 
|   597       j(not_equal, miss, not_taken); |  | 
|   598       // Check access rights to the global object.  This has to happen |  | 
|   599       // after the map check so that we know that the object is |  | 
|   600       // actually a global object. |  | 
|   601       if (object->IsJSGlobalProxy()) { |  | 
|   602         CheckAccessGlobalProxy(reg, scratch, miss); |  | 
|   603       } |  | 
|   604       // The prototype is in old space; load it directly. |  | 
|   605       reg = holder_reg;  // from now the object is in holder_reg |  | 
|   606       mov(reg, Handle<JSObject>(prototype)); |  | 
|   607     } |  | 
|   608  |  | 
|   609     if (save_at_depth == depth) { |  | 
|   610       mov(Operand(esp, kPointerSize), reg); |  | 
|   611     } |  | 
|   612  |  | 
|   613     // Go to the next object in the prototype chain. |  | 
|   614     object = prototype; |  | 
|   615   } |  | 
|   616  |  | 
|   617   // Check the holder map. |  | 
|   618   cmp(FieldOperand(reg, HeapObject::kMapOffset), |  | 
|   619       Immediate(Handle<Map>(holder->map()))); |  | 
|   620   j(not_equal, miss, not_taken); |  | 
|   621  |  | 
|   622   // Log the check depth. |  | 
|   623   LOG(IntEvent("check-maps-depth", depth + 1)); |  | 
|   624  |  | 
|   625   // Perform security check for access to the global object and return |  | 
|   626   // the holder register. |  | 
|   627   ASSERT(object == holder); |  | 
|   628   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |  | 
|   629   if (object->IsJSGlobalProxy()) { |  | 
|   630     CheckAccessGlobalProxy(reg, scratch, miss); |  | 
|   631   } |  | 
|   632   return reg; |  | 
|   633 } |  | 
|   634  |  | 
|   635  |  | 
|   636 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |   545 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 
|   637                                             Register scratch, |   546                                             Register scratch, | 
|   638                                             Label* miss) { |   547                                             Label* miss) { | 
|   639   Label same_contexts; |   548   Label same_contexts; | 
|   640  |   549  | 
|   641   ASSERT(!holder_reg.is(scratch)); |   550   ASSERT(!holder_reg.is(scratch)); | 
|   642  |   551  | 
|   643   // Load current lexical context from the stack frame. |   552   // Load current lexical context from the stack frame. | 
|   644   mov(scratch, Operand(ebp, StandardFrameConstants::kContextOffset)); |   553   mov(scratch, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
|   645  |   554  | 
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1690  |  1599  | 
|  1691   // Check that the code was patched as expected. |  1600   // Check that the code was patched as expected. | 
|  1692   ASSERT(masm_.pc_ == address_ + size_); |  1601   ASSERT(masm_.pc_ == address_ + size_); | 
|  1693   ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |  1602   ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 
|  1694 } |  1603 } | 
|  1695  |  1604  | 
|  1696  |  1605  | 
|  1697 } }  // namespace v8::internal |  1606 } }  // namespace v8::internal | 
|  1698  |  1607  | 
|  1699 #endif  // V8_TARGET_ARCH_IA32 |  1608 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |